-
Notifications
You must be signed in to change notification settings - Fork 21
[TEST DRAFT] #1262
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
[TEST DRAFT] #1262
Conversation
| - name: TC AI PR Reviewer | ||
| uses: topcoder-platform/tc-ai-pr-reviewer@prompt-update | ||
| with: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # The GITHUB_TOKEN is there by default so you just need to keep it like it is and not necessarily need to add it as secret as it will throw an error. [More Details](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The comment about the GITHUB_TOKEN is informative but could be misleading if it suggests that no action is needed. Consider rephrasing to clarify that the token is automatically provided by GitHub Actions and does not need to be manually added as a secret.
| with: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # The GITHUB_TOKEN is there by default so you just need to keep it like it is and not necessarily need to add it as secret as it will throw an error. [More Details](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret) | ||
| LAB45_API_KEY: ${{ secrets.LAB45_API_KEY }} | ||
| exclude: '**/*.json, **/*.md, **/*.jpg, **/*.png, **/*.jpeg, **/*.bmp, **/*.webp' # Optional: exclude patterns separated by commas |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The exclude pattern is optional, but it might be beneficial to ensure that it aligns with the project's requirements. Double-check that the patterns listed here are indeed the ones you want to exclude from the AI PR review process.
| - name: TC AI PR Reviewer | ||
| uses: topcoder-platform/tc-ai-pr-reviewer@prompt-update | ||
| with: | ||
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # The GITHUB_TOKEN is there by default so you just need to keep it like it is and not necessarily need to add it as secret as it will throw an error. [More Details](https://docs.github.com/en/actions/security-guides/automatic-token-authentication#about-the-github_token-secret) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[💡 readability]
The comment about the GITHUB_TOKEN is informative but could be misleading. It suggests that adding the token as a secret will throw an error, which might not be accurate. Consider clarifying that the token is automatically provided by GitHub Actions and does not need to be manually added as a secret.
|
|
||
| // eslint-disable-next-line complexity | ||
| export const ChallengeDetailsPage: FC<Props> = (props: Props) => { | ||
| const { showBannerNotification, removeNotification }: NotificationContextType = useNotification() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[💡 maintainability]
The destructuring of useNotification() into showBannerNotification and removeNotification is correct, but ensure that these functions are used within the component. If they are not used, consider removing the destructuring to avoid unnecessary code.
|
|
||
| // eslint-disable-next-line complexity | ||
| export const ChallengeDetailsPage: FC<Props> = (props: Props) => { | ||
| const { showBannerNotification, removeNotification }: NotificationContextType = useNotification() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The destructuring of NotificationContextType seems unnecessary here. You can directly use const { showBannerNotification, removeNotification } = useNotification(); without specifying the type, as TypeScript can infer it.
| id: 'ai-review-scores-warning', | ||
| message: `AI Review Scores are advisory only to provide immediate, | ||
| educational, and actionable feedback to members. | ||
| AI Review Scores are not influence winner selection.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[❗❗ correctness]
The message string contains a grammatical error: 'AI Review Scores are not influence winner selection.' should be corrected to 'AI Review Scores do not influence winner selection.'
| educational, and actionable feedback to members. | ||
| AI Review Scores are not influence winner selection.`, | ||
| }) | ||
| return () => notification && removeNotification(notification.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[maintainability]
Consider adding error handling for removeNotification(notification.id) to ensure that any issues during the removal process do not cause unintended side effects.
| id: 'ai-review-scores-warning', | ||
| message: `AI Review Scores are advisory only to provide immediate, | ||
| educational, and actionable feedback to members. | ||
| AI Review Scores are not influence winner selection.`, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Typographical error in the message: 'AI Review Scores are not influence winner selection.' should be 'AI Review Scores do not influence winner selection.'
| educational, and actionable feedback to members. | ||
| AI Review Scores are not influence winner selection.`, | ||
| }) | ||
| return () => notification && removeNotification(notification.id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider checking if showBannerNotification is defined before calling it to prevent potential runtime errors.
|
|
||
| const profileContext: Context<ProfileContextData> = createContext(defaultProfileContextData) | ||
|
|
||
| export const useProfileContext = (): ProfileContextData => useContext(profileContext) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[correctness]
Consider adding error handling for cases where useProfileContext is called outside of a ProfileContext.Provider. This can help prevent runtime errors and improve developer experience by providing a clear error message.
| return ( | ||
| <div className={styles.wrap}> | ||
| {notifications.map(n => ( | ||
| <Notification key={n.id} notification={n} onClose={removeNotification} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[💡 readability]
Consider using a more descriptive name for the variable n in the map function to improve readability. For example, notification would make the code clearer.
| return ( | ||
| <div className={styles.wrap}> | ||
| {notifications.map(n => ( | ||
| <Notification key={n.id} notification={n} onClose={removeNotification} /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider renaming the variable n to something more descriptive, such as notification, to improve code readability.
| children: ReactNode, | ||
| }> = props => { | ||
| const profileCtx = useProfileContext() | ||
| const uuid = profileCtx.profile?.userId ?? 'annon' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[correctness]
Using a default user ID of 'annon' might lead to potential issues if multiple anonymous users trigger notifications simultaneously. Consider using a more unique identifier for anonymous users to avoid ID collisions.
| setNotifications(prev => [...prev, newNotification]) | ||
|
|
||
| if (duration > 0) { | ||
| setTimeout(() => removeNotification(id), duration) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[performance]
The setTimeout function does not clear the timeout when the component unmounts, which could lead to memory leaks if the component is unmounted before the timeout completes. Consider storing the timeout ID and clearing it in a useEffect cleanup function.
|
|
||
| const notify = useCallback( | ||
| (message: NotifyPayload, type: NotificationType = 'info', duration = 3000) => { | ||
| const id = `${uuid}[${typeof message === 'string' ? message : message.id}]` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The id generation logic here uses the message as part of the ID, which could lead to potential collisions if the same message is used multiple times. Consider using a more unique identifier, such as a timestamp or a UUID, to ensure uniqueness.
| setNotifications(prev => [...prev, newNotification]) | ||
|
|
||
| if (duration > 0) { | ||
| setTimeout(() => removeNotification(id), duration) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The setTimeout function here does not clear the timeout if the component unmounts before the duration ends. This could lead to memory leaks. Consider storing the timeout ID and clearing it in a useEffect cleanup function.
| const lsKeyPrefix = 'notificationDismissed' | ||
|
|
||
| export const wasDismissed = (id: string): boolean => ( | ||
| (localStorage.getItem(`${lsKeyPrefix}[${id}]`)) !== null |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[❗❗ correctness]
Consider handling potential exceptions from localStorage.getItem. If localStorage is unavailable or disabled, this could throw an error, impacting the application's stability.
| ) | ||
|
|
||
| export const dismiss = (id: string): void => { | ||
| localStorage.setItem(`${lsKeyPrefix}[${id}]`, JSON.stringify(true)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[❗❗ correctness]
Consider handling potential exceptions from localStorage.setItem. If localStorage is full or unavailable, this could throw an error, impacting the application's stability.
| icon?: ReactNode; | ||
| id: string; | ||
| message: string; | ||
| type: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[correctness]
Consider using a union type for notification.type to restrict it to known values like 'banner'. This will improve type safety and prevent errors from unexpected values.
| ) | ||
| } | ||
|
|
||
| return <></> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[maintainability]
Returning an empty fragment (<></>) might not be the best approach if the notification type is not 'banner'. Consider handling other types or providing a fallback UI to improve clarity and maintainability.
| icon?: ReactNode; | ||
| id: string; | ||
| message: string; | ||
| type: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a union type for type to restrict it to known values, such as 'banner' | 'alert' | 'info', to improve type safety.
| ) | ||
| } | ||
|
|
||
| return <></> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Returning an empty fragment <> </> might not be the best approach for handling unsupported notification types. Consider logging a warning or handling other types explicitly.
| @import '../../../styles/includes'; | ||
|
|
||
| .wrap { | ||
| background: #60267D; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[maintainability]
Consider using a CSS variable or a SCSS variable for the background color instead of hardcoding #60267D. This improves maintainability by allowing easier updates and consistency across the application.
| flex: 0 0; | ||
| margin-left: auto; | ||
| border-radius: 50%; | ||
| border: 2px solid white; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[maintainability]
The border color white is hardcoded. Consider using a SCSS variable for consistency and easier updates.
| @import '../../../styles/includes'; | ||
|
|
||
| .wrap { | ||
| background: #60267D; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a variable for the background color instead of a hardcoded hex value to maintain consistency and ease of updates across the project.
| flex: 0 0; | ||
| margin-left: auto; | ||
| border-radius: 50%; | ||
| border: 2px solid white; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using a variable for the border color instead of hardcoding 'white'. This will help maintain consistency and make future updates easier.
| description: 'Content displayed inside the notification banner', | ||
| }, | ||
| persistent: { | ||
| defaultValue: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider using control to define the type of control for the persistent prop in argTypes to enhance the Storybook UI experience.
|
|
||
| export const Primary: Story = { | ||
| args: { | ||
| content: 'Help tooltip', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The content argument is set to a generic string 'Help tooltip'. Consider providing a more descriptive or varied example to better demonstrate the component's capabilities.
| description: 'Content displayed inside the notification banner', | ||
| }, | ||
| persistent: { | ||
| defaultValue: false, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[correctness]
Consider adding a type annotation for defaultValue to ensure type safety and clarity. This can help prevent unintended type-related bugs.
| }, | ||
| }, | ||
| component: NotificationBanner, | ||
| excludeStories: /.*Decorator$/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[💡 maintainability]
The regex /.*Decorator$/ used in excludeStories might unintentionally exclude stories that do not follow the intended naming convention. Consider refining the regex to match specific patterns if necessary.
|
|
||
| import { InformationCircleIcon } from '@heroicons/react/outline' | ||
|
|
||
| import { IconOutline } from '../../svgs' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The import statement for IconOutline seems unnecessary if only XIcon is used. Consider importing XIcon directly to improve clarity and potentially reduce bundle size.
| <div className={styles.inner}> | ||
| {props.icon || ( | ||
| <div className={styles.icon}> | ||
| <InformationCircleIcon className='icon-xl' /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding aria-hidden="true" to the InformationCircleIcon to improve accessibility, as it appears to be decorative.
|
|
||
| {!props.persistent && ( | ||
| <div className={styles.close} onClick={handleClose}> | ||
| <IconOutline.XIcon className='icon-lg' /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider adding aria-label or title to the close button for better accessibility, as screen readers may not convey the purpose of the button without additional context.
|
|
||
| const NotificationBanner: FC<NotificationBannerProps> = props => { | ||
| const handleClose = useCallback(() => { | ||
| props.onClose?.(true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[❗❗ correctness]
The handleClose function calls props.onClose?.(true), which assumes that the onClose callback can handle a boolean argument. Ensure that all usages of NotificationBanner pass an onClose function that correctly handles this argument to avoid potential runtime errors.
| }, [props.onClose]) | ||
|
|
||
| return ( | ||
| <div className={styles.wrap}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[maintainability]
Consider adding an aria-label or role attribute to the close button for better accessibility. This will help screen readers identify the purpose of the button.
| @@ -0,0 +1,2 @@ | |||
| export * from './banner' | |||
| export { default as Notification } from './Notification' | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[❗❗ correctness]
Ensure that the Notification component is properly exported as a default export in the ./Notification module. If it is not, this line will cause an import error.
Related JIRA Ticket:
https://topcoder.atlassian.net/browse/
What's in this PR?