-
Notifications
You must be signed in to change notification settings - Fork 4.1k
add credits number in teacher dashboard #7840
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
Conversation
WalkthroughThe changes introduce a new function Changes
Assessment against linked issues
Possibly related PRs
Suggested reviewers
Warning There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure. 🔧 eslint
warning eslint@8.57.1: This version is no longer supported. Please see https://eslint.org/version-support for other options. Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
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.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (1)
app/core/api/user-credits.js (1)
Line range hint
1-40
: Consider implementing request throttling and error handling.Since credits are fetched directly without caching:
- Consider implementing request throttling to prevent API abuse
- Add comprehensive error handling for network failures
- Consider adding a loading state indicator in the UI
Example implementation for the teacher dashboard:
// Throttle requests using lodash's throttle const throttledGetStudentCredits = _.throttle(getStudentCredits, 5000); // Add error handling try { const credits = await throttledGetStudentCredits(action, student); } catch (error) { // Handle specific error cases if (error.status === 429) { // Rate limit exceeded } // Network error, etc. }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (4)
app/core/api/user-credits.js
(2 hunks)app/core/constants.js
(2 hunks)app/locale/en.js
(1 hunks)ozaria/site/components/teacher-dashboard/modals/ModalEditStudent.vue
(6 hunks)
🔇 Additional comments (17)
app/core/api/user-credits.js (2)
35-35
: LGTM!
The export addition maintains consistent style and alphabetical ordering.
4-4
:
Add input validation and URL encoding for security.
The new endpoint implementation has potential security concerns:
- Missing input validation for the
student
parameter - No URL encoding for the query parameter which could lead to URL injection
Apply this diff to address the issues:
-const getStudentCredits = (action, student) => fetchJson(`/db/user-credits/${action}?student=${student}`)
+const getStudentCredits = (action, student) => {
+ if (!student) {
+ throw new Error('Student parameter is required')
+ }
+ return fetchJson(`/db/user-credits/${action}?student=${encodeURIComponent(student)}`)
+}
Also, verify the endpoint pattern difference:
✅ Verification successful
Add input validation and URL encoding for student parameter
Add validation and encoding to prevent potential security issues:
-const getStudentCredits = (action, student) => fetchJson(`/db/user-credits/${action}?student=${student}`)
+const getStudentCredits = (action, student) => {
+ if (!student) {
+ throw new Error('Student parameter is required')
+ }
+ return fetchJson(`/db/user-credits/${action}?student=${encodeURIComponent(student)}`)
+}
Regarding the endpoint pattern difference between /db/credits/
and /db/user-credits/
:
- This is intentional as
getCredits()
andgetStudentCredits()
serve different purposes - All user-specific credit operations consistently use the
/db/user-credits/
prefix - All general credit operations use the
/db/credits/
prefix - The pattern is consistent with the rest of the codebase
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check for consistency in credit-related endpoint patterns
# Search for all credit-related API endpoint usages
rg -A 2 "'/db/(user-)?credits/" --type js
# Search for any documentation about the endpoint pattern
fd -e md -e txt . | xargs rg "credits.*endpoint|api.*credits"
Length of output: 876
Script:
#!/bin/bash
# Let's check for all API endpoint patterns in the user-credits.js file
cat app/core/api/user-credits.js
Length of output: 862
app/core/constants.js (2)
130-131
: LGTM!
The constant is properly exported with correct comma separation.
109-110
: Clarify the constant name USER_CREDIT_HACKSTACK_KEY
The constant name contains 'HACKSTACK' which seems unusual. Should this be 'HASHSTACK' instead? Additionally, please add a comment explaining the purpose and usage of this constant for better maintainability.
Let's check if this is used consistently elsewhere:
ozaria/site/components/teacher-dashboard/modals/ModalEditStudent.vue (5)
9-10
: LGTM: Imports are well-organized
The new imports for credit-related functionality are properly structured and align with the PR objective.
32-32
: LGTM: Data property properly initialized
The studentCredits
property is correctly initialized to null
, following Vue best practices for async data.
125-127
: LGTM: Method implementation is clean
The getCredits
method is concise and follows Vue method implementation patterns.
192-194
: LGTM: Template changes are consistent
The credit information display follows the existing template structure and properly uses i18n for localization.
9-10
: Verify translation keys and API endpoint
Please ensure:
- All required translation keys exist in the i18n files
- The API endpoint is properly configured and accessible
Also applies to: 32-32, 44-57, 113-113, 125-127, 192-194
app/locale/en.js (8)
Line range hint 1-2
: LGTM!
The module export syntax is correct.
Line range hint 4-5
: LGTM!
The nativeDescription
and englishDescription
properties are defined correctly.
Line range hint 8-24
: LGTM!
The ozaria_home
section contains various localized strings related to the Ozaria home page. The property names and values seem appropriate.
Line range hint 26-52
: LGTM!
The new_home
section contains localized strings for the new home page. The property names and values are defined correctly.
Line range hint 54-62
: LGTM!
The modal
section defines localized strings for modal dialogs. The property names and values are appropriate.
Line range hint 64-71
: LGTM!
The not_found
section contains localized strings for the "not found" page. The property names and values are defined correctly.
Line range hint 73-80
: LGTM!
The diplomat_suggestion
section provides localized strings for suggesting users to become diplomats. The property names and values are appropriate.
Line range hint 82-6108
: Verify the completeness and accuracy of the localized strings.
The provided code snippet contains a large number of localized strings for various sections of the application, such as play_level
, code
, share_progress_modal
, login
, signup
, recover
, items
, common
, units
, etc.
While the structure and syntax of the localized strings appear to be correct, it's important to verify the completeness and accuracy of the translations. Here are a few suggestions:
- Review each section and ensure that all the necessary strings are included and properly translated.
- Check for any missing or incomplete translations and fill in the gaps.
- Verify that the translations accurately convey the intended meaning and context of each string.
- Test the application with the localized strings to ensure they are displayed correctly and fit well within the user interface.
Reviewing and verifying the localized strings thoroughly will help ensure a high-quality localization of the application.
@@ -92,6 +110,7 @@ export default { | |||
async mounted () { | |||
await this.fetchLevelsForClassroom(this.classroom._id) | |||
this.levels = this.getLevelsForClassroom(this.classroom._id) | |||
await this.getCredits() |
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.
🛠️ Refactor suggestion
Add error handling for getCredits call
The getCredits
call should include error handling to gracefully handle API failures.
Consider wrapping it in a try-catch:
async mounted () {
await this.fetchLevelsForClassroom(this.classroom._id)
this.levels = this.getLevelsForClassroom(this.classroom._id)
- await this.getCredits()
+ try {
+ await this.getCredits()
+ } catch (error) {
+ console.error('Failed to fetch student credits:', error)
+ // Consider showing a user-friendly error message
+ noty({
+ text: this.$t('errors.loading_credits'),
+ type: 'error',
+ layout: 'center',
+ timeout: 3000
+ })
+ }
Committable suggestion skipped: line range outside the PR's diff.
creditMessage () { | ||
if (this.studentCredits && this.studentCredits.result?.length > 0) { | ||
const credit = this.studentCredits.result[0] | ||
const durAmount = credit.durationAmount > 1 ? credit.durationAmount : $.i18n.t('hackstack.creditMessage_the') | ||
return $.i18n.t('hackstack.creditMessage_creditcreditsleft-creditinitialcredits-c', { | ||
creditCreditsLeft: credit.creditsLeft, | ||
creditInitialCredits: credit.initialCredits, | ||
durAmount, | ||
creditDurationKey: credit.durationKey, | ||
}) | ||
} else { | ||
return 'loading...' | ||
} | ||
}, |
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.
🛠️ Refactor suggestion
Consider improving error handling and localization
The computed property has several areas for improvement:
- The "loading..." message should be localized
- There's no error state handling
- The null check could be more robust
Consider this improved implementation:
creditMessage () {
- if (this.studentCredits && this.studentCredits.result?.length > 0) {
+ if (!this.studentCredits) {
+ return $.i18n.t('common.loading')
+ }
+
+ if (!this.studentCredits.result || this.studentCredits.result.length === 0) {
+ return $.i18n.t('hackstack.no_credits_available')
+ }
+
const credit = this.studentCredits.result[0]
const durAmount = credit.durationAmount > 1 ? credit.durationAmount : $.i18n.t('hackstack.creditMessage_the')
return $.i18n.t('hackstack.creditMessage_creditcreditsleft-creditinitialcredits-c', {
creditCreditsLeft: credit.creditsLeft,
creditInitialCredits: credit.initialCredits,
durAmount,
creditDurationKey: credit.durationKey,
})
- } else {
- return 'loading...'
- }
}
Committable suggestion skipped: line range outside the PR's diff.
creditDurationKey: credit.durationKey, | ||
}) | ||
} else { | ||
return 'loading...' |
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.
i18n?
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.
ok.
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.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (5)
ozaria/site/components/teacher-dashboard/modals/ModalEditStudent.vue (1)
44-57
: Consider enhancing the creditMessage computed propertyWhile the i18n implementation is good, the property could benefit from more robust error handling:
- Add explicit error state handling
- Improve null checks for nested properties
creditMessage () { - if (this.studentCredits && this.studentCredits.result?.length > 0) { + if (this.studentCredits?.error) { + return $.i18n.t('errors.loading_credits') + } + + if (!this.studentCredits || !Array.isArray(this.studentCredits.result)) { + return $.i18n.t('common.loading') + } + + if (this.studentCredits.result.length === 0) { + return $.i18n.t('hackstack.no_credits') + } + const credit = this.studentCredits.result[0] const durAmount = credit.durationAmount > 1 ? credit.durationAmount : $.i18n.t('hackstack.creditMessage_the') return $.i18n.t('hackstack.creditMessage_creditcreditsleft-creditinitialcredits-c', { creditCreditsLeft: credit.creditsLeft, creditInitialCredits: credit.initialCredits, durAmount, creditDurationKey: credit.durationKey, }) - } else { - return $.i18n.t('common.loading') - } }app/locale/en.js (4)
Line range hint
1-6109
: Consider breaking down this large translation file into smaller modulesThe current file is quite large with over 6000 lines of translations. Consider splitting it into smaller, more focused modules (e.g., by feature area) to improve maintainability. You could have separate files for:
- Core/common translations
- Game-specific translations
- Admin/teacher translations
- Marketing/landing page translations
This would make it easier to manage translations and reduce the risk of merge conflicts.
Line range hint
1-6109
: Standardize string formatting and markup approachThere are inconsistencies in how formatted text is handled in translations:
- Some strings use HTML tags:
<strong>
,<br>
, etc.- Others use markdown-style formatting:
**bold**
,__variable__
- Some use both approaches mixed together
Consider standardizing on a single approach (preferably markdown) to make translations more maintainable and reduce the risk of XSS vulnerabilities from HTML in translations.
Line range hint
1-6109
: Review security implications of HTML in translationsThe presence of raw HTML in translation strings could pose XSS security risks if not properly sanitized before rendering. Consider:
- Using a sanitization library to clean HTML in translations
- Moving URLs to a separate configuration file
- Using placeholders for dynamic content instead of direct HTML
This will help prevent potential security vulnerabilities while maintaining formatting flexibility.
- "<strong>Hello</strong> <a href='http://example.com'>Link</a>" + "**Hello** [Link](__exampleUrl__)"
Line range hint
1-6109
: Standardize variable placeholder formatThere are inconsistent approaches to variable placeholders throughout the translations:
- Some use
__variable__
- Others use
{{variable}}
- Some use both formats in the same string
Standardize on a single format (preferably
__variable__
as it appears to be more commonly used) to improve maintainability and reduce potential errors.Also consider standardizing on single quotes for string literals throughout the file for consistency.
📜 Review details
Configurati
8000
on used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
app/locale/en.js
(1 hunks)ozaria/site/components/teacher-dashboard/modals/ModalEditStudent.vue
(6 hunks)
🔇 Additional comments (4)
ozaria/site/components/teacher-dashboard/modals/ModalEditStudent.vue (4)
9-10
: LGTM!
The imports are correctly placed and follow naming conventions.
32-32
: LGTM!
The data property is correctly initialized to null and follows Vue naming conventions.
113-113
: Add error handling for getCredits call
The getCredits call should include error handling to gracefully handle API failures.
192-194
: LGTM!
The template addition follows the existing structure and correctly uses i18n for translations.
async getCredits () { | ||
this.studentCredits = await getStudentCredits(USER_CREDIT_HACKSTACK_KEY, this.studentId) | ||
}, |
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.
🛠️ Refactor suggestion
Enhance getCredits method with loading state and error handling
The method should manage loading state and handle potential API errors.
async getCredits () {
+ try {
+ this.studentCredits = { loading: true }
this.studentCredits = await getStudentCredits(USER_CREDIT_HACKSTACK_KEY, this.studentId)
+ } catch (error) {
+ console.error('Failed to fetch student credits:', error)
+ this.studentCredits = { error }
+ noty({
+ text: this.$t('errors.loading_credits'),
+ type: 'error',
+ layout: 'center',
+ timeout: 3000
+ })
+ }
}
fix ENG-1352
since credits cannot be cached so does not use vue store but instead using API directly in view

Summary by CodeRabbit
Release Notes
New Features
Improvements
Bug Fixes