├── .nvmrc ├── .dockerignore ├── docker-compose.yml ├── tutor ├── resources │ ├── styles │ │ ├── components │ │ │ ├── app.scss │ │ │ ├── dialog.scss │ │ │ ├── index.scss │ │ │ ├── markdown.scss │ │ │ ├── times.scss │ │ │ ├── confirm-leave-mixin.scss │ │ │ ├── practice-button.scss │ │ │ ├── course-title-banner.scss │ │ │ ├── top-nav-bar │ │ │ │ ├── preview-add-course-btn.scss │ │ │ │ ├── question-library.scss │ │ │ │ ├── plugable.scss │ │ │ │ └── center-controls.scss │ │ │ ├── branding │ │ │ │ └── course.scss │ │ │ ├── no-periods.scss │ │ │ ├── tours │ │ │ │ ├── anchor.scss │ │ │ │ ├── mini-notice.scss │ │ │ │ ├── centered-wheel.scss │ │ │ │ ├── tips-now-or-later.scss │ │ │ │ └── navbar.scss │ │ │ ├── tri-state-checkbox.scss │ │ │ ├── tutor-dialog.scss │ │ │ ├── icon.scss │ │ │ ├── registration │ │ │ │ └── index.scss │ │ │ ├── invalid-page.scss │ │ │ ├── plan-stats.scss │ │ │ ├── modals │ │ │ │ ├── error.scss │ │ │ │ └── warning.scss │ │ │ ├── copy-on-focus-input.scss │ │ │ ├── cc-student-redirect.scss │ │ │ └── tours.scss │ │ ├── global │ │ │ ├── navbar.scss │ │ │ ├── menus.scss │ │ │ ├── maths.scss │ │ │ ├── links.scss │ │ │ ├── misc.scss │ │ │ ├── externals.scss │ │ │ ├── popover.scss │ │ │ ├── alerts.scss │ │ │ ├── forms.scss │ │ │ ├── tooltip.scss │ │ │ └── progress-bars.scss │ │ ├── variables │ │ │ ├── paths.scss │ │ │ └── registration.scss │ │ ├── book-content │ │ │ ├── figure.scss │ │ │ ├── link-to-learning.scss │ │ │ ├── examples.scss │ │ │ ├── page-title.scss │ │ │ ├── os-teacher.scss │ │ │ ├── equations.scss │ │ │ └── typography.scss │ │ ├── definitions.scss │ │ └── mixins │ │ │ ├── drag-and-drop.scss │ │ │ ├── left-stripe.scss │ │ │ ├── exercise-cards-column-layout.scss │ │ │ └── tasks.scss │ ├── images │ │ ├── cc-sunset │ │ │ └── view-analytics.svg │ │ ├── ost-hero.jpg │ │ ├── rice-logo.png │ │ ├── openstax-logo-white.png │ │ ├── courses │ │ │ ├── biology-background.jpg │ │ │ ├── physics-background.jpg │ │ │ ├── hs_physics-book-thumbnail.png │ │ │ └── concepts_biology-book-thumbnail.png │ │ ├── icons │ │ │ └── mpp-exclude-action.svg │ │ └── learning-guide │ │ │ ├── flag-blue.svg │ │ │ ├── flag-green.svg │ │ │ ├── flag-grey.svg │ │ │ └── flag-yellow.svg │ └── fonts │ │ ├── merriweather-v8-latin-300.woff │ │ ├── merriweather-v8-latin-700.woff │ │ ├── merriweather-v8-latin-300.woff2 │ │ ├── merriweather-v8-latin-700.woff2 │ │ ├── merriweather-v8-latin-regular.woff │ │ ├── merriweather-v8-latin-regular.woff2 │ │ ├── merriweather-v8-latin-300italic.woff │ │ ├── merriweather-v8-latin-300italic.woff2 │ │ ├── merriweather-v8-latin-700italic.woff │ │ ├── merriweather-v8-latin-700italic.woff2 │ │ ├── merriweather-v8-latin-regularitalic.woff │ │ ├── architects-daughter-v6-latin-regular.woff │ │ ├── architects-daughter-v6-latin-regular.woff2 │ │ └── merriweather-v8-latin-regularitalic.woff2 ├── src │ ├── components │ │ ├── student-course.spec.js │ │ ├── tours │ │ │ └── custom │ │ │ │ ├── footer.js │ │ │ │ ├── student-welcome-to-tutor.jsx │ │ │ │ └── buttons.js │ │ ├── button-link.js │ │ ├── link.js │ │ ├── small-text.js │ │ ├── match-for-tutor.js │ │ ├── text.js │ │ ├── icons │ │ │ ├── info.js │ │ │ ├── sort.js │ │ │ └── add.js │ │ ├── notes │ │ │ └── getRangeRect.js │ │ ├── navbar │ │ │ ├── username.jsx │ │ │ ├── secondary-toolbar-button.jsx │ │ │ └── account-link.jsx │ │ ├── enroll │ │ │ ├── invalid-code.jsx │ │ │ ├── invalid-lms.jsx │ │ │ ├── dropped-student.jsx │ │ │ ├── course-ended.jsx │ │ │ └── invalid-lms-use.jsx │ │ ├── support-email-link.jsx │ │ ├── toasts │ │ │ ├── add-edit.js │ │ │ └── course-settings-saved.js │ │ ├── impersonation-warning.js │ │ ├── onboarding │ │ │ └── ux │ │ │ │ └── index.ts │ │ ├── content-page.js │ │ ├── my-courses │ │ │ └── create-a-course.jsx │ │ ├── scroll-tracker.js │ │ └── payments │ │ │ └── modal.jsx │ ├── screens │ │ ├── lms-pair │ │ │ ├── pair-request.js │ │ │ ├── router.js │ │ │ ├── create-course.jsx │ │ │ ├── styles.scss │ │ │ ├── index.jsx │ │ │ └── app.js │ │ ├── assignment-grade │ │ │ └── styles.scss │ │ ├── teacher-gradebook │ │ │ ├── styles.scss │ │ │ └── styles.js │ │ ├── assignment-review │ │ │ ├── styles.scss │ │ │ └── exercise-type.js │ │ ├── performance-forecast │ │ │ ├── styles │ │ │ │ ├── teacher.scss │ │ │ │ ├── statistics.scss │ │ │ │ └── teacher-student.scss │ │ │ └── chapter-section-type.js │ │ ├── task │ │ │ ├── back-button.js │ │ │ └── step │ │ │ │ └── spy-info.js │ │ ├── student-dashboard │ │ │ ├── styles.scss │ │ │ ├── styles │ │ │ │ ├── card.scss │ │ │ │ ├── empty-card.scss │ │ │ │ └── dont-forget-panel.scss │ │ │ └── event-type-icon.js │ │ ├── assignment-edit │ │ │ ├── unknown.js │ │ │ └── details.js │ │ ├── reference-book │ │ │ ├── styles │ │ │ │ └── exercise.scss │ │ │ ├── book-title.jsx │ │ │ └── section-title.jsx │ │ ├── new-course │ │ │ ├── back-button.jsx │ │ │ ├── index.jsx │ │ │ ├── steps.js │ │ │ └── offering-unavail.jsx │ │ ├── question-library │ │ │ ├── unsaved-dialog.jsx │ │ │ └── loading-display.jsx │ │ ├── my-courses │ │ │ └── styles.scss │ │ ├── qa-view │ │ │ └── view-toggle.jsx │ │ └── screen-styles.scss │ ├── helpers │ │ ├── function.js │ │ ├── production.js │ │ ├── moment-range.js │ │ ├── router.js │ │ ├── string.ts │ │ ├── offering.ts │ │ ├── durations.js │ │ ├── immutable.js │ │ ├── number.js │ │ ├── hooks.ts │ │ ├── flux-to-mobx.js │ │ ├── course-data.js │ │ ├── clipboard.js │ │ ├── background-wrapper.js │ │ ├── object.js │ │ ├── exercise.js │ │ ├── task.js │ │ ├── backInfo.js │ │ ├── period.ts │ │ └── reload.js │ ├── models │ │ ├── subject-order.ts │ │ ├── student-tasks │ │ │ └── student.ts │ │ ├── tour │ │ │ └── actions │ │ │ │ ├── open-actions-menu.ts │ │ │ │ ├── open-support-menu.ts │ │ │ │ └── hover-exercise.ts │ │ ├── research-surveys.ts │ │ ├── user │ │ │ └── viewed-tour-stat.ts │ │ ├── course │ │ │ ├── teacher-student.ts │ │ │ ├── term.ts │ │ │ ├── teacher-profile.ts │ │ │ └── pair-to-lms.ts │ │ ├── ecosystems.ts │ │ ├── ecosystems │ │ │ └── book.ts │ │ ├── app │ │ │ └── nav-history.ts │ │ └── related-content.ts │ ├── config.ts │ ├── primitives.js │ └── tours │ │ ├── page-tips-reminder.json │ │ ├── review-metrics.json │ │ └── performance-forecast.json ├── specs │ ├── acceptance │ │ ├── helpers │ │ │ ├── set-role.js │ │ │ ├── images-dir.js │ │ │ ├── working-directory.js │ │ │ ├── index.js │ │ │ ├── global-teardown.js │ │ │ └── open-page.js │ │ └── survey.spec.js │ ├── components │ │ ├── __snapshots__ │ │ │ ├── go-to-top.spec.js.snap │ │ │ ├── navbar.spec.js.snap │ │ │ ├── template-modal.spec.js.snap │ │ │ ├── notes.spec.js.snap │ │ │ ├── multi-select.spec.jsx.snap │ │ │ └── content-page.spec.js.snap │ │ ├── go-to-top.spec.js │ │ ├── content-page.spec.js │ │ ├── template-modal.spec.js │ │ ├── tours │ │ │ ├── custom │ │ │ │ └── instructor-welcome-to-tutor.spec.jsx │ │ │ └── anchor.spec.jsx │ │ ├── select.spec.jsx │ │ ├── best-practices-tip.spec.js │ │ ├── radio-input.spec.jsx │ │ ├── checkbox-input.spec.js │ │ ├── course-breadcrumb.spec.jsx │ │ ├── warning-model.spec.jsx │ │ ├── navbar │ │ │ └── preview-add-course-btn.spec.jsx │ │ ├── onboarding │ │ │ ├── redeem-code.spec.jsx │ │ │ └── pay-now-or-later.spec.jsx │ │ ├── invalid-page.spec.jsx │ │ ├── my-courses │ │ │ └── pending-verification.spec.jsx │ │ └── buttons │ │ │ └── reload-page.spec.js │ ├── integration │ │ ├── student-gradebook.spec.js │ │ ├── dashboard.spec.js │ │ └── helpers.js │ ├── screens │ │ ├── new-course │ │ │ ├── __snapshots__ │ │ │ │ ├── index.spec.jsx.snap │ │ │ │ ├── build-course.spec.jsx.snap │ │ │ │ └── offering-title.spec.jsx.snap │ │ │ ├── index.spec.jsx │ │ │ └── build-course.spec.jsx │ │ ├── reference-book │ │ │ └── __snapshots__ │ │ │ │ ├── book-title.spec.js.snap │ │ │ │ └── section-title.spec.js.snap │ │ ├── task │ │ │ ├── helpers.js │ │ │ └── steps │ │ │ │ └── question-stem.spec.js │ │ └── assignment-edit │ │ │ ├── homework │ │ │ └── exercise-controls.spec.jsx │ │ │ └── questions-overview.spec.jsx │ ├── factories │ │ ├── practice-questions.js │ │ ├── .eslintrc.js │ │ ├── ecosystem.js │ │ └── definitions.js │ ├── helpers │ │ ├── object.spec.js │ │ ├── modal-wrapper.js │ │ ├── test-router.js │ │ └── scores-data.js │ ├── e2e │ │ └── course-roster.e2e.ts │ ├── models │ │ ├── tour │ │ │ └── region.spec.ts │ │ ├── grading │ │ │ └── templates.spec.ts │ │ ├── student-tasks.spec.ts │ │ ├── courses │ │ │ └── offerings.spec.ts │ │ └── purchases.spec.ts │ └── global.d.ts ├── api │ ├── pages │ │ ├── dummy-physics-page.json │ │ ├── 334f8b61-30eb-4475-8e05-5260a4866b4b@4.68.json │ │ └── 0e58aa87-2e09-40a7-8bf3-269b2fa16509.json │ ├── steps │ │ ├── step-id-2-1.json │ │ ├── step-id-8-1.json │ │ ├── step-id-6-4.json │ │ ├── step-id-practice-5.json │ │ ├── step-id-5-2.json │ │ ├── step-id-6-2.json │ │ ├── step-id-5-1.json │ │ ├── step-id-5-3.json │ │ ├── step-id-6-1.json │ │ ├── step-id-6-3.json │ │ ├── step-id-6-4-full.json │ │ ├── step-id-practice-4.json │ │ ├── step-id-9-3 │ │ │ └── recovery │ │ │ │ └── PUT.json │ │ ├── step-id-9-1.json │ │ ├── step-id-3-1.json │ │ ├── step-id-4-2.json │ │ ├── step-id-4-2 │ │ │ ├── recovery │ │ │ │ └── PUT.json │ │ │ └── PATCH.json │ │ ├── step-id-4-5.json │ │ ├── step-id-9-1 │ │ │ └── PATCH.json │ │ └── step-id-4-5 │ │ │ └── PATCH.json │ ├── user.json │ ├── notifications.json │ ├── tasks │ │ └── 2.json │ ├── plans │ │ ├── 13 │ │ │ └── stats.json │ │ ├── 5.json │ │ ├── 7.json │ │ ├── 13.json │ │ ├── 3.json │ │ ├── 2.json │ │ └── 1.json │ ├── user │ │ └── courses │ │ │ └── no-periods.json │ ├── ecosystems.json │ └── enrollment_changes │ │ └── POST.json ├── index.html ├── jest-playwright.config.js ├── index.js └── lms-pair.js ├── .github ├── CODEOWNERS └── ISSUE_TEMPLATE │ ├── template-epic.md │ ├── template-change.md │ └── template-story.md ├── Brewfile ├── shared ├── resources │ ├── styles │ │ ├── variables │ │ │ └── paths.scss │ │ ├── components │ │ │ ├── surety-guard.scss │ │ │ ├── close.scss │ │ │ ├── smart-overflow.scss │ │ │ ├── html │ │ │ │ └── index.scss │ │ │ ├── exercise │ │ │ │ └── group.scss │ │ │ ├── exercise-badges │ │ │ │ └── index.scss │ │ │ └── ox-colored-stripe.scss │ │ ├── demo.scss │ │ ├── mixins │ │ │ └── input.scss │ │ ├── main.scss │ │ └── no-conflict.scss │ └── images │ │ ├── openstax-white-books.png │ │ └── icons │ │ ├── icon-video-placeholder.svg │ │ ├── video-placeholder-icon.svg │ │ ├── icon-video.svg │ │ └── icon-end.svg ├── .DS_Store ├── src │ ├── types.ts │ ├── components │ │ ├── get-position-mixin.js │ │ ├── static.js │ │ ├── ox-colored-stripe.js │ │ ├── scroll-to-top.js │ │ ├── buttons │ │ │ └── close-button.js │ │ └── markdown.js │ ├── model │ │ ├── exercise │ │ │ ├── author.ts │ │ │ ├── attachment.ts │ │ │ ├── solution.ts │ │ │ └── format.ts │ │ └── bignum.ts │ └── helpers │ │ └── props.js ├── specs │ ├── components │ │ ├── buttons │ │ │ ├── __snapshots__ │ │ │ │ └── close-button.spec.js.snap │ │ │ ├── close-button.spec.js │ │ │ └── refresh-button.spec.js │ │ ├── __snapshots__ │ │ │ ├── html.spec.js.snap │ │ │ ├── spy-mode.spec.jsx.snap │ │ │ ├── exercise-identifier-link.spec.js.snap │ │ │ └── ox-colored-stripe.spec.js.snap │ │ ├── ox-colored-stripe.spec.js │ │ ├── corner-ribbon.spec.jsx │ │ └── static.spec.jsx │ ├── factories │ │ ├── helpers.js │ │ └── index.ts │ ├── helpers │ │ ├── errors.ts │ │ ├── index.ts │ │ └── fake-dom-node.js │ ├── model │ │ └── exercise │ │ │ ├── answer.spec.ts │ │ │ └── tags-association.spec.ts │ └── .eslintrc.js ├── api │ ├── notifications.json │ ├── exercise │ │ └── index.js │ ├── breadcrumbs │ │ └── steps.json │ └── html │ │ └── data.json ├── index.html └── full-build.js ├── exercises ├── resources │ └── styles │ │ ├── exercise-preview.scss │ │ ├── global │ │ ├── font-awesome.scss │ │ └── widgets.scss │ │ ├── variables │ │ └── paths.scss │ │ ├── card-background.scss │ │ ├── mixins │ │ ├── generic.scss │ │ └── editing-panes.scss │ │ ├── app.scss │ │ ├── navbar.scss │ │ ├── vocabulary.scss │ │ ├── preview.scss │ │ └── vendor-variables.scss ├── src │ ├── components │ │ ├── search │ │ │ └── controls.jsx │ │ ├── tags │ │ │ ├── nursingBooks.js │ │ │ ├── time.jsx │ │ │ ├── dok.jsx │ │ │ └── blooms.jsx │ │ └── exercise-state.jsx │ ├── models │ │ ├── toasts.ts │ │ ├── exercises │ │ │ ├── delegation.ts │ │ │ └── image.ts │ │ └── user.ts │ └── ux.ts ├── index.html ├── specs │ ├── helpers.js │ └── .eslintrc.js └── README.md ├── .ignore ├── configs ├── test │ ├── jest.style-mock.js │ ├── jest.shared.js │ ├── cypress-tutor.json │ ├── jest.exercises.js │ ├── cypress-healthcheck.json │ ├── jest.tutor.js │ └── jest.tutor-acceptance.js └── playwright.config.ts ├── .node-inspectorrc ├── .gitattributes ├── docker ├── docker-compose.dev.yml └── nginx.conf ├── .codecov.yml ├── bin ├── checkinputs ├── health-check ├── screenshot ├── karma ├── debug ├── test-unit ├── serve ├── tdd ├── test-e2e └── lint ├── script ├── build ├── test ├── ci └── generate-tutor-boot-screen ├── .editorconfig ├── AUTHORS ├── LICENSING ├── types └── index.d.ts ├── .gitignore ├── docker-compose.override.yml └── docker-compose.exercises.yml /.nvmrc: -------------------------------------------------------------------------------- 1 | v16.14.0 2 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/app.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/global/navbar.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/variables/paths.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/src/components/student-course.spec.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/src/components/tours/custom/footer.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/src/screens/lms-pair/pair-request.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @openstax/tutor-devs 2 | -------------------------------------------------------------------------------- /Brewfile: -------------------------------------------------------------------------------- 1 | brew "yarn" 2 | brew "shellcheck" 3 | -------------------------------------------------------------------------------- /shared/resources/styles/variables/paths.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/dialog.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/index.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/markdown.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/times.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /exercises/resources/styles/exercise-preview.scss: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /exercises/resources/styles/global/font-awesome.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /shared/resources/styles/components/surety-guard.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/confirm-leave-mixin.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/practice-button.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.ignore: -------------------------------------------------------------------------------- 1 | .git 2 | .codecov* 3 | **/api/*.json 4 | *.snap 5 | -------------------------------------------------------------------------------- /configs/test/jest.style-mock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /tutor/src/helpers/function.js: -------------------------------------------------------------------------------- 1 | export default { 2 | empty() {}, 3 | }; 4 | -------------------------------------------------------------------------------- /tutor/src/screens/assignment-grade/styles.scss: -------------------------------------------------------------------------------- 1 | @import '../screen-styles'; 2 | -------------------------------------------------------------------------------- /tutor/src/screens/teacher-gradebook/styles.scss: -------------------------------------------------------------------------------- 1 | @import '../screen-styles'; 2 | -------------------------------------------------------------------------------- /shared/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/shared/.DS_Store -------------------------------------------------------------------------------- /tutor/resources/images/cc-sunset/view-analytics.svg: -------------------------------------------------------------------------------- 1 | ../course-preview/view-analytics.svg -------------------------------------------------------------------------------- /tutor/resources/styles/book-content/figure.scss: -------------------------------------------------------------------------------- 1 | .os-figure { 2 | 3 | 4 | 5 | } 6 | -------------------------------------------------------------------------------- /.node-inspectorrc: -------------------------------------------------------------------------------- 1 | { 2 | "save-live-edit": true, 3 | "preload": true, 4 | "hidden": ["node_modules/"] 5 | } 6 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | screenshots/* filter=lfs diff=lfs merge=lfs -text 2 | screenshots/** filter=lfs diff=lfs merge=lfs -text 3 | -------------------------------------------------------------------------------- /shared/resources/styles/components/close.scss: -------------------------------------------------------------------------------- 1 | &-close-x { 2 | &::before { 3 | content: "\00d7"; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /tutor/resources/images/ost-hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/ost-hero.jpg -------------------------------------------------------------------------------- /tutor/src/helpers/production.js: -------------------------------------------------------------------------------- 1 | const isProd = (process.env.NODE_ENV === 'production'); 2 | 3 | export { isProd }; 4 | -------------------------------------------------------------------------------- /tutor/resources/images/rice-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/rice-logo.png -------------------------------------------------------------------------------- /tutor/resources/styles/components/course-title-banner.scss: -------------------------------------------------------------------------------- 1 | .course-title-banner { 2 | @include tutor-booksplash-background(); 3 | } 4 | -------------------------------------------------------------------------------- /exercises/src/components/search/controls.jsx: -------------------------------------------------------------------------------- 1 | // nothing for now 2 | export default function SearchControls() { 3 | return null; 4 | } 5 | -------------------------------------------------------------------------------- /tutor/src/screens/assignment-review/styles.scss: -------------------------------------------------------------------------------- 1 | @import '../screen-styles'; 2 | 3 | .stacked-modal-backdrop { 4 | z-index: 1050; 5 | } 6 | -------------------------------------------------------------------------------- /tutor/resources/images/openstax-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/openstax-logo-white.png -------------------------------------------------------------------------------- /shared/resources/images/openstax-white-books.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/shared/resources/images/openstax-white-books.png -------------------------------------------------------------------------------- /shared/resources/styles/components/smart-overflow.scss: -------------------------------------------------------------------------------- 1 | &-smart-overflow { 2 | overflow-y: auto; 3 | overflow-x: hidden; 4 | max-height: none; 5 | } -------------------------------------------------------------------------------- /tutor/specs/acceptance/helpers/set-role.js: -------------------------------------------------------------------------------- 1 | export default async function setRole(role) { 2 | return await global.__SERVER__.setRole(role); 3 | } 4 | -------------------------------------------------------------------------------- /tutor/src/screens/performance-forecast/styles/teacher.scss: -------------------------------------------------------------------------------- 1 | .performance-forecast.teacher { 2 | nav { 3 | @include make-row(); 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /docker/docker-compose.dev.yml: -------------------------------------------------------------------------------- 1 | version: '3.5' 2 | services: 3 | serve: 4 | image: "openstax/tutor-js:dev" 5 | ports: 6 | - "8000:80" 7 | 8 | -------------------------------------------------------------------------------- /tutor/api/pages/dummy-physics-page.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"Dummy Physics page", 3 | "chapter_section": [], 4 | "content_html": "A bunch of html" 5 | } 6 | -------------------------------------------------------------------------------- /tutor/api/steps/step-id-2-1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "step-id-2-1", 3 | "type": "interactive", 4 | "content_url": "http://connexions.github.io/simulations" 5 | } -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-300.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-300.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-700.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-700.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-300.woff2 -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-700.woff2 -------------------------------------------------------------------------------- /tutor/resources/images/courses/biology-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/courses/biology-background.jpg -------------------------------------------------------------------------------- /tutor/resources/images/courses/physics-background.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/courses/physics-background.jpg -------------------------------------------------------------------------------- /tutor/specs/components/__snapshots__/go-to-top.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`GoToTop matches snapshot 1`] = `null`; 4 | -------------------------------------------------------------------------------- /tutor/src/helpers/moment-range.js: -------------------------------------------------------------------------------- 1 | import moment from 'moment'; 2 | import { extendMoment } from 'moment-range'; 3 | 4 | export default extendMoment(moment); 5 | -------------------------------------------------------------------------------- /tutor/src/screens/performance-forecast/styles/statistics.scss: -------------------------------------------------------------------------------- 1 | .statistics { 2 | .clue { 3 | font-size: 1rem; 4 | color: $tutor-neutral; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-regular.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-regular.woff2 -------------------------------------------------------------------------------- /tutor/resources/styles/components/top-nav-bar/preview-add-course-btn.scss: -------------------------------------------------------------------------------- 1 | .preview-add-course-nav-button { 2 | display: flex; 3 | align-items: center; 4 | } 5 | -------------------------------------------------------------------------------- /tutor/resources/styles/variables/registration.scss: -------------------------------------------------------------------------------- 1 | $registration-base-x-padding: 30px; 2 | $registration-base-y-padding: 80px; 3 | $registration-top-margin: 20px; 4 | -------------------------------------------------------------------------------- /tutor/specs/acceptance/helpers/images-dir.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { imagesDir: path.join(__dirname, '../../../../screenshots') }; 4 | -------------------------------------------------------------------------------- /.codecov.yml: -------------------------------------------------------------------------------- 1 | comment: 2 | layout: "header, diff, changes, uncovered, tree" 3 | behavior: default 4 | 5 | # To Turn off comments completely: 6 | # comment: false 7 | -------------------------------------------------------------------------------- /shared/src/types.ts: -------------------------------------------------------------------------------- 1 | export type ID = string | number 2 | 3 | export interface JSON { 4 | readonly [text: string]: JSON | JSON[] | string | number | boolean 5 | } 6 | -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-300italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-300italic.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-300italic.woff2 -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-700italic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-700italic.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-700italic.woff2 -------------------------------------------------------------------------------- /tutor/resources/images/courses/hs_physics-book-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/courses/hs_physics-book-thumbnail.png -------------------------------------------------------------------------------- /bin/checkinputs: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -eq 0 ]; then 4 | echo "No project to build was given. usage:" 5 | echo "$0 " 6 | exit 1 7 | fi -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-regularitalic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-regularitalic.woff -------------------------------------------------------------------------------- /tutor/resources/styles/components/branding/course.scss: -------------------------------------------------------------------------------- 1 | .course-branding { 2 | &[data-is-beta=true] { 3 | &::after { 4 | content: ' Beta'; 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/no-periods.scss: -------------------------------------------------------------------------------- 1 | .no-periods-message { 2 | border: 1px solid $tutor-neutral-lite; 3 | text-align: center; 4 | padding: 30px 0; 5 | } 6 | -------------------------------------------------------------------------------- /tutor/specs/components/__snapshots__/navbar.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Main Navbar renders and matches snapshot 1`] = `null`; 4 | -------------------------------------------------------------------------------- /tutor/resources/fonts/architects-daughter-v6-latin-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/architects-daughter-v6-latin-regular.woff -------------------------------------------------------------------------------- /tutor/resources/fonts/architects-daughter-v6-latin-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/architects-daughter-v6-latin-regular.woff2 -------------------------------------------------------------------------------- /tutor/resources/fonts/merriweather-v8-latin-regularitalic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/fonts/merriweather-v8-latin-regularitalic.woff2 -------------------------------------------------------------------------------- /shared/resources/styles/components/html/index.scss: -------------------------------------------------------------------------------- 1 | &-has-html { 2 | @include openstax-tables(); 3 | 4 | .frame-wrapper { 5 | margin: 1rem 0; 6 | } 7 | } 8 | 9 | 10 | -------------------------------------------------------------------------------- /tutor/api/user.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Johhny Tran", 3 | "is_admin": false, 4 | "school_location": "domestic_school", 5 | "profile_url": "http://accounts.foo.bar/profile" 6 | } 7 | -------------------------------------------------------------------------------- /tutor/resources/images/courses/concepts_biology-book-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openstax/tutor-js/HEAD/tutor/resources/images/courses/concepts_biology-book-thumbnail.png -------------------------------------------------------------------------------- /tutor/specs/acceptance/helpers/working-directory.js: -------------------------------------------------------------------------------- 1 | const os = require('os'); 2 | const path = require('path'); 3 | 4 | module.exports = path.join(os.tmpdir(), 'tutor-acceptance'); 5 | -------------------------------------------------------------------------------- /configs/test/jest.shared.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | coverageDirectory: '../coverage/shared/', 3 | rootDir: '../../shared', 4 | preset: '../configs/test/jest.config.json', 5 | }; 6 | -------------------------------------------------------------------------------- /tutor/api/pages/334f8b61-30eb-4475-8e05-5260a4866b4b@4.68.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"Fake Physics - Chapter Opener", 3 | "chapter_section": [3,0], 4 | "content_html": "A bunch of html" 5 | } 6 | -------------------------------------------------------------------------------- /tutor/src/components/button-link.js: -------------------------------------------------------------------------------- 1 | import { OXButtonLink } from 'shared'; 2 | import TutorRouter from '../helpers/router'; 3 | 4 | export default OXButtonLink.make(TutorRouter, 'Tutor'); 5 | -------------------------------------------------------------------------------- /tutor/api/notifications.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "id": "1", 3 | "message": "Warning: Updates will happen soon! Site will be down." 4 | }, { 5 | "id": "2", 6 | "message": "These are test messages." 7 | }] -------------------------------------------------------------------------------- /tutor/resources/styles/components/top-nav-bar/question-library.scss: -------------------------------------------------------------------------------- 1 | &.nav-viewQuestionsLibrary { 2 | box-shadow: none; 3 | position: relative; 4 | border-bottom: 1px solid #d5d5d5; 5 | } -------------------------------------------------------------------------------- /tutor/resources/styles/global/menus.scss: -------------------------------------------------------------------------------- 1 | .dropdown-menu { 2 | 3 | border: 1px solid $tutor-neutral-light; 4 | 5 | &.hide { 6 | display: none !important; 7 | } 8 | 9 | } 10 | -------------------------------------------------------------------------------- /bin/health-check: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | NPM=$(npm bin) 5 | cmd=${1:-run} 6 | args=${@:2} 7 | $NPM/cypress $cmd --config-file configs/test/cypress-healthcheck.json $args 8 | -------------------------------------------------------------------------------- /tutor/api/pages/0e58aa87-2e09-40a7-8bf3-269b2fa16509.json: -------------------------------------------------------------------------------- 1 | { 2 | "title":"Updated Tutor HS Physics Content - legacy", 3 | "chapter_section": [3,1], 4 | "content_html": "A bunch of html" 5 | } 6 | -------------------------------------------------------------------------------- /tutor/src/models/subject-order.ts: -------------------------------------------------------------------------------- 1 | export const SubjectOrder = [ 2 | 'Math', 3 | 'Science', 4 | 'Social Sciences', 5 | 'Humanities', 6 | 'Business', 7 | 'AP® Courses', 8 | ] 9 | -------------------------------------------------------------------------------- /bin/screenshot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export OX_PROJECT=tutor-acceptance 4 | export CACHE=true 5 | 6 | $(npm bin)/jest --runInBand --all --updateSnapshot --config ./configs/test/jest.$OX_PROJECT.js "${@:2}" 7 | -------------------------------------------------------------------------------- /script/build: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | cd "$(dirname "$0")/.." || exit 111 3 | source ./script/bootstrap || exit 111 4 | 5 | # shellcheck disable=SC2068 6 | do_progress_quiet "Building dist" \ 7 | ./bin/build tutor $@ 8 | -------------------------------------------------------------------------------- /tutor/resources/styles/book-content/link-to-learning.scss: -------------------------------------------------------------------------------- 1 | // This file is part of the book-content mixin and should not be included directly 2 | [data-alt='QR Code representing a URL'] { 3 | display: none; 4 | } 5 | -------------------------------------------------------------------------------- /tutor/specs/acceptance/helpers/index.js: -------------------------------------------------------------------------------- 1 | import snapshotPage from './snapshot-page'; 2 | import openPage from './open-page'; 3 | import setRole from './set-role'; 4 | 5 | export { snapshotPage, openPage, setRole }; 6 | -------------------------------------------------------------------------------- /bin/karma: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | bin/checkinputs "$@" 6 | 7 | export OX_PROJECT=$1 8 | echo Karma: $OX_PROJECT 9 | 10 | karma start configs/test/karma.config.js --auto-watch --no-single-run 11 | -------------------------------------------------------------------------------- /tutor/specs/integration/student-gradebook.spec.js: -------------------------------------------------------------------------------- 1 | context('Student Gradebook', () => { 2 | 3 | beforeEach(() => { 4 | cy.visit('/course/1/gradebook') 5 | cy.disableTours(); 6 | }); 7 | 8 | }) 9 | -------------------------------------------------------------------------------- /tutor/src/models/student-tasks/student.ts: -------------------------------------------------------------------------------- 1 | import { BaseModel, field, NEW_ID } from 'shared/model'; 2 | 3 | export class TaskedStudent extends BaseModel { 4 | @field role_id = NEW_ID; 5 | @field name = ''; 6 | } 7 | -------------------------------------------------------------------------------- /exercises/resources/styles/variables/paths.scss: -------------------------------------------------------------------------------- 1 | $fa-font-path: './fonts'; 2 | 3 | $bootstrap-path: '~bootstrap/less/'; 4 | $widgets-path: '~react-widgets/lib/less/'; 5 | $material-path: '~bootstrap-material-design/less/'; 6 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/tours/anchor.scss: -------------------------------------------------------------------------------- 1 | // compensate for the dropdown caret to the right 2 | .dropdown-toggle .tour-anchor { 3 | padding-right: 2 * $caret-width; 4 | margin-right: -2 * $caret-width; 5 | } 6 | -------------------------------------------------------------------------------- /tutor/specs/screens/new-course/__snapshots__/index.spec.jsx.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`NewCourse wrapper renders and matches snapshot 1`] = ` 4 | 5 | 6 | 7 | `; 8 | -------------------------------------------------------------------------------- /configs/test/cypress-tutor.json: -------------------------------------------------------------------------------- 1 | { 2 | "baseUrl": "http://localhost:8110", 3 | "integrationFolder": "tutor/specs/integration", 4 | "screenshotsFolder": "screenshots/tutor", 5 | "videosFolder": "screenshots/tutor" 6 | } 7 | -------------------------------------------------------------------------------- /configs/test/jest.exercises.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | coverageDirectory: '../coverage/exercises/', 3 | rootDir: '../../exercises', 4 | cacheDirectory: '/tmp/exercises', 5 | preset: '../configs/test/jest.config.json', 6 | }; 7 | -------------------------------------------------------------------------------- /shared/src/components/get-position-mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | getTopPosition(el) { 3 | if (!el) { return 0; } 4 | return el.getBoundingClientRect().top - document.body.getBoundingClientRect().top; 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /tutor/src/components/link.js: -------------------------------------------------------------------------------- 1 | import { OXLink } from 'shared'; 2 | import TutorRouter from '../helpers/router'; 3 | const TutorLink = OXLink.make(TutorRouter, 'Tutor'); 4 | TutorLink.displayName = 'TutorLink'; 5 | export default TutorLink; 6 | -------------------------------------------------------------------------------- /shared/specs/components/buttons/__snapshots__/close-button.spec.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Close Button Component has proper classes 1`] = ` 4 | 10 | ); 11 | }); 12 | 13 | export default BackButton; 14 | -------------------------------------------------------------------------------- /bin/tdd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | on_termination() { 6 | echo killing webpack $WEBPACK_PID 7 | kill -TERM $WEBPACK_PID 2>/dev/null 8 | } 9 | 10 | bin/checkinputs "$@" 11 | 12 | trap on_termination EXIT 13 | 14 | export OX_PROJECT=$1 15 | echo TDD: $OX_PROJECT 16 | 17 | 18 | webpack-dev-server --config webpack.config.js & 19 | WEBPACK_PID=$! 20 | echo webpack started pid: $WEBPACK_PID 21 | 22 | ./bin/test "$@" 23 | -------------------------------------------------------------------------------- /shared/src/components/scroll-to-top.js: -------------------------------------------------------------------------------- 1 | import { useEffect } from 'react'; 2 | import { withRouter } from 'react-router'; 3 | 4 | const ScrollToTop = ({ children, location: { pathname } }) => { 5 | useEffect(() => { 6 | if (window.scrollTo) { 7 | window.scrollTo(0, 0); 8 | } 9 | }, [pathname]); 10 | 11 | return children || null; 12 | }; 13 | 14 | export default withRouter(ScrollToTop); 15 | -------------------------------------------------------------------------------- /tutor/resources/styles/components/tours/tips-now-or-later.scss: -------------------------------------------------------------------------------- 1 | .tips-now-or-later { 2 | .joyride-tooltip__ { 3 | &footer { 4 | width: 220px; 5 | } 6 | 7 | &button { 8 | &--primary { 9 | float: left; 10 | } 11 | 12 | &--skip { 13 | float: right; 14 | padding: 6px 12px; 15 | margin: 0; 16 | color: $tutor-dark-blue; 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tutor/src/screens/student-dashboard/styles/empty-card.scss: -------------------------------------------------------------------------------- 1 | .student-dashboard { 2 | .card.empty { 3 | margin-top: 0; 4 | border-right: none; 5 | border-bottom: none; 6 | border-left: none; 7 | border-radius: 0; 8 | padding: 20px; 9 | text-align: center; 10 | flex-direction: row; 11 | justify-content: center; 12 | 13 | .spinner { 14 | margin-right: 1rem; 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /shared/src/model/exercise/attachment.ts: -------------------------------------------------------------------------------- 1 | import type Exercise from '../exercise' 2 | import { 3 | BaseModel, field, modelize, getParentOf, 4 | } from '../../model'; 5 | 6 | export default 7 | class ExerciseAttachment extends BaseModel { 8 | 9 | get exercise() { return getParentOf(this) } 10 | 11 | @field asset: any; 12 | 13 | constructor() { 14 | super() 15 | modelize(this) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /tutor/src/components/enroll/invalid-code.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Modal, Alert } from 'react-bootstrap'; 3 | 4 | export default function invalidCode() { 5 | return ( 6 | 7 | 8 | The provided enrollment code is not valid. Please verify the enrollment code and try again. 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /tutor/src/components/enroll/invalid-lms.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Modal, Alert } from 'react-bootstrap'; 3 | 4 | export default function invalidCode() { 5 | return ( 6 | 7 | 8 | The provided enrollment code is not valid. Please verify the enrollment code and try again. 9 | 10 | 11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /shared/specs/model/exercise/answer.spec.ts: -------------------------------------------------------------------------------- 1 | import Answer from '../../../src/model/exercise/answer' 2 | 3 | describe('Exercise Question', () => { 4 | 5 | it('validates', () => { 6 | const answer = new Answer() 7 | expect(answer.validity).toEqual({ 'part': 'Answer Distractor', 'valid': false }); 8 | answer.content_html = 'a choice'; 9 | expect(answer.validity.valid).toBe(true) 10 | }); 11 | 12 | }); 13 | -------------------------------------------------------------------------------- /shared/specs/model/exercise/tags-association.spec.ts: -------------------------------------------------------------------------------- 1 | import TagsAssociation, { Tag } from '../../../src/model/exercise/tags-association' 2 | 3 | describe('Exercise Tags Association', () => { 4 | 5 | it('splits and re-assembles parts', () => { 6 | const ta = new TagsAssociation() 7 | ta.all.push(new Tag('lo:stax-phys:1-2-1')) 8 | expect(ta.includes({ type: 'lo', value: '1-2-1' })).toBeTruthy() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /tutor/specs/components/select.spec.jsx: -------------------------------------------------------------------------------- 1 | import Select from '../../src/components/select'; 2 | import { Formik as F } from 'formik'; 3 | 4 | describe('Select', () => { 5 | let props; 6 | 7 | beforeEach(() => { 8 | props = { 9 | name: 'select1', 10 | }; 11 | }); 12 | 13 | it('matches snapshot', () => { 14 | expect.snapshot(