Skip to content

feat(PM-1503): View scorecard implementation #1186

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

Open
wants to merge 2 commits into
base: PM-1502-scorecards
Choose a base branch
from

Conversation

hentrymartin
Copy link
Collaborator

Related JIRA Ticket:

https://topcoder.atlassian.net/browse/PM-1503

What's in this PR?

  • View scorecard implementation
  • Integrated with backend

{
id,
}: UseFetchScorecardParams,
): Scorecard {

Choose a reason for hiding this comment

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

The return type of the useFetchScorecard function is declared as Scorecard, but it should be Scorecard | undefined to account for the initial undefined state of the data returned by useSWR.

fetcher,
)

return data as Scorecard

Choose a reason for hiding this comment

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

Consider handling the case where data might be undefined before returning it. This will prevent potential runtime errors if the data is not yet loaded.

@@ -94,4 +96,9 @@ export interface Scorecard {
category: string
status: ScorecardStatus
index?: number
version: string

Choose a reason for hiding this comment

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

Consider adding a default value or validation for the version property to ensure consistency across scorecards.

@@ -94,4 +96,9 @@ export interface Scorecard {
category: string
status: ScorecardStatus
index?: number
version: string
challengeType: string
minScore: number

Choose a reason for hiding this comment

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

It might be beneficial to validate minScore and maxScore to ensure minScore is not greater than maxScore.

challengeType: string
minScore: number
maxScore: number
scorecardGroups: ScorecardGroup[]

Choose a reason for hiding this comment

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

Ensure that scorecardGroups is properly initialized to avoid potential null or undefined errors when accessing this property.

display: flex;
flex-direction: row;
padding: 32px;
background-color: #F6F7F9;

Choose a reason for hiding this comment

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

Consider using a CSS variable for the background color #F6F7F9 to maintain consistency and ease future updates.

margin-bottom: 20px;
.label {
font-weight: 700;
font-family: "Nunito Sans", sans-serif;

Choose a reason for hiding this comment

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

The font-family 'Nunito Sans' is used here. Ensure that this font is loaded correctly in the application to avoid fallback to default fonts.

font-weight: 400;
font-family: "Nunito Sans", sans-serif;
font-size: 16px;
color: #0A0A0A;

Choose a reason for hiding this comment

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

Consider using a CSS variable for the color #0A0A0A to maintain consistency and ease future updates.

color: #0A0A0A;
text-transform: capitalize;
&.active {
color: #00797A;

Choose a reason for hiding this comment

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

Consider using a CSS variable for the color #00797A to maintain consistency and ease future updates.

}

&.inactive, &.deleted {
color: #767676;

Choose a reason for hiding this comment

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

Consider using a CSS variable for the color #767676 to maintain consistency and ease future updates.


&.inactive, &.deleted {
color: #767676;
font-family: 'Inter', sans-serif;

Choose a reason for hiding this comment

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

The font-family 'Inter' is used here. Ensure that this font is loaded correctly in the application to avoid fallback to default fonts.

flex-direction: column;
}
}
}

Choose a reason for hiding this comment

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

Add a newline at the end of the file to follow best practices and ensure compatibility with various tools.

}

const ScorecardDetails: FC<ScorecardDetailsProps> = (props: ScorecardDetailsProps) => {
const getStatusClassname = (): string => styles[ScorecardStatusLabels[props.scorecard.status]?.toLowerCase()]

Choose a reason for hiding this comment

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

Consider memoizing the getStatusClassname function using useCallback to prevent unnecessary re-calculations on each render.

<div className={styles.item}>
<div className={styles.label}>Status</div>
<div
className={cn(styles.value, getStatusClassname())}

Choose a reason for hiding this comment

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

The cn function is used for conditional class names. Ensure that getStatusClassname() always returns a valid class name to avoid potential runtime errors.

}
}
}
}

Choose a reason for hiding this comment

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

It's a good practice to ensure that files end with a newline character. This can help prevent issues with certain tools and version control systems.

<div className={styles.groupNumber}>{`Group ${index + 1}`}</div>
<div className={styles.groupInfo}>
<div className={styles.name}>{group.name}</div>
<div>{group.weight}</div>

Choose a reason for hiding this comment

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

Consider adding a label or unit to the group.weight value for better clarity, especially if it represents a specific metric or percentage.

@import '@libs/ui/styles/includes';

.container {
background-color: #E0E4E84D;

Choose a reason for hiding this comment

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

Consider using a more descriptive variable name for the color value #E0E4E84D to improve readability and maintainability.

.section {
.heading {
padding: 12px 16px;
background-color: #00797A;

Choose a reason for hiding this comment

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

Consider using a more descriptive variable name for the color value #00797A to improve readability and maintainability.

}
}
.questions {
background-color: #FFFFFF;

Choose a reason for hiding this comment

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

Consider using a more descriptive variable name for the color value #FFFFFF to improve readability and maintainability.

background-color: #FFFFFF;
padding: 32px 20px;
.question {
background-color: #F6F7F9;

Choose a reason for hiding this comment

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

Consider using a more descriptive variable name for the color value #F6F7F9 to improve readability and maintainability.

padding: 20px 16px;
display: flex;
flex-direction: row;
color: #0A0A0A;

Choose a reason for hiding this comment

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

Consider using a more descriptive variable name for the color value #0A0A0A to improve readability and maintainability.

}
}
}
}

Choose a reason for hiding this comment

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

Add a newline at the end of the file to adhere to POSIX standards and improve compatibility with various tools.

<div className={cn(styles.question, {
[styles.notLast]: index + 1 !== section.questions.length,
})}
>

Choose a reason for hiding this comment

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

Consider adding a key prop to the div element here to ensure each question has a unique key, which is important for React's reconciliation process.

</div>
<div className={styles.detailItem}>
<div className={styles.label}>Document Upload:</div>
{/* This will be added once upload functionality works */}

Choose a reason for hiding this comment

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

The comment here indicates that the upload functionality is not yet implemented. Ensure that there is a plan or task to address this in the future to avoid leaving incomplete features in the codebase.

line-height: 30px;
}
}
}

Choose a reason for hiding this comment

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

Consider adding a newline at the end of the file to adhere to POSIX standards and improve compatibility with various tools.

const ViewScorecardPage: FC = () => {
const { scorecardId = '' }: { scorecardId?: string } = useParams<{ scorecardId: string }>()
const { profile }: ProfileContextData = useContext(profileContext)
const isAdmin = profile?.roles.includes(UserRole.administrator)

Choose a reason for hiding this comment

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

Consider checking if profile is defined before accessing roles to prevent potential runtime errors if profile is undefined.

[],
)

const scorecard = useFetchScorecard({ id: scorecardId as string })

Choose a reason for hiding this comment

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

It might be beneficial to handle cases where useFetchScorecard returns an error or null to improve user experience and prevent rendering issues.

<PageWrapper
pageTitle='Software General Review Scorecard'
breadCrumb={breadCrumb}
rightHeader={isAdmin && (

Choose a reason for hiding this comment

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

The rightHeader prop conditionally renders the Edit Scorecard button based on isAdmin. Ensure that the Button component handles cases where iconToLeft and icon are not provided, to prevent unexpected behavior.

@@ -57,21 +57,23 @@ export const toolTitle: string = ToolTitle.review
export const reviewRoutes: ReadonlyArray<PlatformRoute> = [
// Review App Root
{
authRequired: true,
children: [

Choose a reason for hiding this comment

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

The authRequired property was moved from line 60 to line 62. Ensure that this change is intentional and does not affect the route's authentication logic.

element: <ScorecardsListPage />,
id: 'list-scorecards-page',
route: '',
},
{
authRequired: false,

Choose a reason for hiding this comment

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

It might be more secure to require authentication for viewing individual scorecards. Consider setting authRequired: true for the ViewScorecardPage to ensure that only authorized users can access specific scorecard details.

@@ -100,6 +100,7 @@ export const RouterProvider: FC<RouterProviderProps> = (props: RouterProviderPro

function getRouteElement(route: PlatformRoute): JSX.Element {

console.log(route, 'route')

Choose a reason for hiding this comment

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

Debugging statement console.log(route, 'route') should be removed before merging to ensure clean production code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant