8000 features adding hs credit license to the teacher by smallst · Pull Request #7931 · codecombat/codecombat · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

features adding hs credit license to the teacher #7931

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

Merged
merged 7 commits into from
May 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions app/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,8 @@ if (isCodeCombat) {
courseIDs.GAME_DEVELOPMENT_3,
courseIDs.COMPUTER_SCIENCE_4,
courseIDs.COMPUTER_SCIENCE_5,
courseIDs.COMPUTER_SCIENCE_6
courseIDs.COMPUTER_SCIENCE_6,
courseIDs.HACKSTACK,
]
otherOrderedCourseIDs = [
otherCourseIDs.CHAPTER_ONE,
Expand Down Expand Up @@ -318,6 +319,7 @@ if (isCodeCombat) {

otherCourseIDs = {
JUNIOR: '65f32b6c87c07dbeb5ba1936',
HACKSTACK: '663b25f11c568468efc8adde',
INTRODUCTION_TO_COMPUTER_SCIENCE: '560f1a9f22961295f9427742',
GAME_DEVELOPMENT_1: '5789587aad86a6efb573701e',
WEB_DEVELOPMENT_1: '5789587aad86a6efb573701f',
Expand Down Expand Up @@ -356,7 +358,8 @@ if (isCodeCombat) {
otherCourseIDs.GAME_DEVELOPMENT_3,
otherCourseIDs.COMPUTER_SCIENCE_4,
otherCourseIDs.COMPUTER_SCIENCE_5,
otherCourseIDs.COMPUTER_SCIENCE_6
otherCourseIDs.COMPUTER_SCIENCE_6,
otherCourseIDs.HACKSTACK,
]

hourOfCodeOptions = {
Expand Down
3 changes: 3 additions & 0 deletions app/locale/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -2750,6 +2750,8 @@ module.exports = {
full_license: 'Full License',
starter_license: 'Starter License',
customized_license: 'Customized License',
hackstack_license: 'AI HackStack License',
hackstack_credits: 'Credits: __limit__ prompts / __durationAmount__ __durationKey__(s)',
trial: 'Trial',
hoc_welcome: 'Happy Computer Science Education Week',
hoc_title: 'Hour of Code Games - Free Activities to Learn Real Coding Languages',
Expand Down Expand Up @@ -4544,6 +4546,7 @@ module.exports = {

admin: {
license_type_full: 'Full Courses',
license_type_hackstack: 'Hackstack',
license_type_customize: 'Customize Courses',
},

Expand Down
4 changes: 4 additions & 0 deletions app/models/Prepaid.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,10 @@ module.exports = (Prepaid = (function () {
}
const includedCourseIDs = this.get('includedCourseIDs')
if (includedCourseIDs) {
const credit = this.get('properties')?.creditDetails
if (credit && includedCourseIDs[0] === utils.courseIDs.HACKSTACK) {
return i18n.t('teacher.hackstack_license') + i18n.t('teacher.hackstack_credits', credit)
}
return i18n.t('teacher.customized_license') + ': ' + (includedCourseIDs.map(id => utils.courseAcronyms[id])).join('+')
} else {
return i18n.t('teacher.full_license')
Expand Down
12 changes: 11 additions & 1 deletion app/schemas/models/prepaid.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,17 @@ const PrepaidSchema = c.object({ title: 'Prepaid', required: ['type'] }, {
properties: c.object({ additionalProperties: true },
{
activatedByTeacher: { type: 'boolean', description: 'if this Prepaid used for teacher-activation code.' },
testStudentOnly: { type: 'boolean', description: 'if this Prepaid is for test-student only' }
testStudentOnly: { type: 'boolean', description: 'if this Prepaid is for test-student only' },
creditDetails: {
type: 'object',
description: 'if the prepaid is for HACKSTACK, add credits details here.',
properties: {
operation: { type: 'string', enum: ['HACKSTACK_QUERY', 'LEVEL_CHAT_BOT'] },
durationAmount: { type: 'number' },
durationKey: { type: 'string', enum: ['day', 'week', 'month'] },
limit: { type: 'number' },
},
},
}),
exhausted: { type: 'boolean' },
startDate: c.stringDate(),
Expand Down
12 changes: 12 additions & 0 deletions app/schemas/models/user_credit.schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,18 @@ const UserCreditSchema = c.object({
}
)
),
licenses: c.array(
{
title: 'License Credits',
}, {
prepaidId: c.objectId(),
endDate: c.date(),
operation: c.shortString(),
durationKey: c.shortString(),
durationAmount: c.int(),
limit: c.int(),
},
),
extras: c.array(
{
title: 'Extra credits'
Expand Down
2 changes: 1 addition & 1 deletion app/templates/admin/administer-user-modal.pug
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,7 @@ block modal-body-content
else
h4.small(style="max-width: 700px") Licenses start at 12am PT on the start date and end at 11:59pm PT on the end date listed.
+license-form-group('Number of Licenses')(id="seats-input" type="number", name="maxRedeemers", min="1")
+license-type(view.licenseType, view.licensePresets, view.utils)
+license-type(view.licenseType, view.licensePresets, view.utils, view.creditDetails)
+license-form-group('Start Date')(type="date" name="startDate" value=view.momentTimezone().tz(view.timeZone).format('YYYY-MM-DD'))
+license-form-group('End Date')(type="date" name="endDate" value=view.momentTimezone().tz(view.timeZone).add(1, 'year').format('YYYY-MM-DD'))
- userTimeZone = view.userTimeZone
Expand Down
12 changes: 10 additions & 2 deletions app/templates/courses/enrollments-view.pug
Original file line number Diff line number Diff line change
Expand Up @@ -106,15 +106,23 @@ mixin prepaidCard(prepaid, className)
.prepaid-card.bg-navy.text-center.p-a-2.rtl-allowed(class=className)
h1.m-t-2.m-b-0= prepaid.openSpots()
- var includedCourseIDs = prepaid.get('includedCourseIDs')
- var credit = prepaid.get('properties') == null ? null : prepaid.get('properties').creditDetails
- var hackstackLicense = credit && includedCourseIDs.length == 1 && includedCourseIDs[0] == view.utils.courseIDs.HACKSTACK
if prepaid.get('type') === 'starter_license'
div.rtl-allowed(data-i18n="teacher.starter_licenses")
else if hackstackLicense
div.rtl-allowed(data-i18n="teacher.hackstack_license")
else if includedCourseIDs
div.rtl-allowed(data-i18n="teacher.customized_license")
else
div.rtl-allowed(data-i18n="teacher.full_license")
div.includedCourses
each id in (includedCourseIDs || [])
i.course-acronym=view.utils.courseAcronyms[id]
if hackstackLicense
i.course-acronym
= translate('teacher.hackstack_credits', credit)
else
each id in (includedCourseIDs || [])
i.course-acronym=view.utils.courseAcronyms[id]
div.m-t-1.rtl-allowed(dir="auto")
i.small-details
if prepaid.usedSpots() === 1
Expand Down
21 changes: 20 additions & 1 deletion app/templates/teachers/common/license-type-mixin.pug
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
mixin license-type(licenseType, licensePresets, utils)
mixin license-type(licenseType, licensePresets, utils, credit)
.form-group
label
span Licenses Type
Expand All @@ -8,6 +8,10 @@ mixin license-type(licenseType, licensePresets, utils)
label.license-type
input(type="radio", name="licenseType", value="all", checked=licenseType==='all')
span(data-i18n="admin.license_type_full")
.radio
label.license-type
input(type="radio", name="licenseType", value="hackstack", checked=licenseType==='hackstack')
span(data-i18n="admin.license_type_hackstack")
each v, preset in licensePresets
.radio
label.license-type
Expand All @@ -23,3 +27,18 @@ mixin license-type(licenseType, licensePresets, utils)
label.course-name
input(type="checkbox", name="includedCourseIDs", value=courseID, checked=key==='INTRODUCTION_TO_COMPUTER_SCIENCE' || key==='JUNIOR')
span=utils.courseAcronyms[courseID]
#credits-details
if licenseType === 'hackstack'
span
| Every
label.duration-amount
input(type="number", min=1, name="durationAmount", value=credit.amount)
label.duration-key
select#credit-duration-select(name="durationKey")
option(value="day" selected=credit.key==='day') Day
option(value="week" selected=credit.key==='week') Week
option(value="month" selected=credit.key==='month') Month
label.credit-limit
input(type="number", min=1, name='creditLimit', value=credit.limit)
span
| prompts
22 changes: 22 additions & 0 deletions app/views/admin/AdministerUserModal.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,11 @@ module.exports = (AdministerUserModal = (function () {
this.licenseType = 'all'
this.licensePresets = LICENSE_PRESETS
this.esportsType = 'basic'
this.creditDetails = {
amount: 1,
key: 'week',
limit: 30,
}
this.utils = utils
options.models = [this.user] // For ModelModal to generate a Treema of this user
this.models = [this.user]
Expand Down Expand Up @@ -284,6 +289,8 @@ module.exports = (AdministerUserModal = (function () {
if (!attrs.endDate || !attrs.startDate || !(attrs.endDate > attrs.startDate)) { return }
attrs.endDate = attrs.endDate + ' ' + '23:59' // Otherwise, it ends at 12 am by default which does not include the date indicated
let timeZone = this.timeZone
let isHackstack = false
let hackstackCredits = {}
if (attrs.userTimeZone?.[0] === 'on') {
timeZone = this.userTimeZone
}
Expand All @@ -297,6 +304,17 @@ module.exports = (AdministerUserModal = (function () {
if (attrs.licenseType in this.licensePresets) {
attrs.includedCourseIDs = this.licensePresets[attrs.licenseType]
}
if (attrs.licenseType === 'hackstack') {
attrs.includedCourseIDs = [utils.courseIDs.HACKSTACK]
isHackstack = true
hackstackCredits.operation = 'HACKSTACK_QUERY'
hackstackCredits.durationAmount = parseInt(attrs.durationAmount)
hackstackCredits.durationKey = attrs.durationKey
hackstackCredits.limit = parseInt(attrs.creditLimit)
delete attrs.durationAmount
delete attrs.durationKey
delete attrs.creditLimit
}
if ((attrs.licenseType !== 'all') && !attrs.includedCourseIDs.length) { return }
delete attrs.licenseType

Expand All @@ -307,6 +325,10 @@ module.exports = (AdministerUserModal = (function () {
adminAdded: me.id
}
})
if (isHackstack) {
attrs.properties.creditDetails = hackstackCredits
hackstackCredits = {}
}
const prepaid = new Prepaid(attrs)
prepaid.save()
this.state = 'creating-prepaid'
Expand Down
Loading
0