From a1776f4366935f627bcdce38cfbd9f50f13ac512 Mon Sep 17 00:00:00 2001 From: "Dave St.Germain" Date: Mon, 30 Mar 2020 11:59:31 -0400 Subject: [PATCH] Added calculator component (#33) TNL-7138 --- src/courseware/course/Course.jsx | 4 +- .../course/calculator/calculator.scss | 27 ++ src/courseware/course/calculator/index.jsx | 393 ++++++++++++++++++ src/courseware/course/calculator/messages.js | 31 ++ src/data/api.js | 1 + 5 files changed, 455 insertions(+), 1 deletion(-) create mode 100644 src/courseware/course/calculator/calculator.scss create mode 100644 src/courseware/course/calculator/index.jsx create mode 100644 src/courseware/course/calculator/messages.js diff --git a/src/courseware/course/Course.jsx b/src/courseware/course/Course.jsx index 9dced10b..a7ad8032 100644 --- a/src/courseware/course/Course.jsx +++ b/src/courseware/course/Course.jsx @@ -14,6 +14,7 @@ import Sequence from './sequence'; import CourseBreadcrumbs from './CourseBreadcrumbs'; import { Header, CourseTabsNavigation } from '../../course-header'; import CourseSock from './course-sock'; +import Calculator from './calculator'; import messages from './messages'; import { useModel } from '../../model-store'; @@ -48,7 +49,7 @@ function Course({ if (courseStatus === 'loaded') { const { - org, number, title, isStaff, tabs, verifiedMode, + org, number, title, isStaff, tabs, verifiedMode, showCalculator, } = course; return ( <> @@ -89,6 +90,7 @@ function Course({ previousSequenceHandler={previousSequenceHandler} /> {verifiedMode && } + {showCalculator && } ); diff --git a/src/courseware/course/calculator/calculator.scss b/src/courseware/course/calculator/calculator.scss new file mode 100644 index 00000000..6a64a20d --- /dev/null +++ b/src/courseware/course/calculator/calculator.scss @@ -0,0 +1,27 @@ +.calculator { + position: fixed; + left: 0; + right: 0; + bottom: 0; + z-index: 100; + .calculator-trigger { + cursor: pointer; + display: inline-block; + position: relative; + z-index: 2; + background-color: #f1f1f1; + border: solid 1px #ddd; + border-bottom: none; + border-top-left-radius: .3rem; + border-top-right-radius: .3rem; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + &:before { + border-radius: .5rem; + } + } + .calculator-content { + background-color: #f1f1f1; + box-shadow: 0 -1px 0 0 #ddd; + } +} diff --git a/src/courseware/course/calculator/index.jsx b/src/courseware/course/calculator/index.jsx new file mode 100644 index 00000000..7634fb9b --- /dev/null +++ b/src/courseware/course/calculator/index.jsx @@ -0,0 +1,393 @@ +import React, { Component } from 'react'; +import { Collapsible } from '@edx/paragon'; +import { getConfig } from '@edx/frontend-platform'; +import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth'; +import { + FormattedMessage, injectIntl, intlShape, +} from '@edx/frontend-platform/i18n'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { + faCalculator, faQuestionCircle, faTimesCircle, faEquals, +} from '@fortawesome/free-solid-svg-icons'; +import messages from './messages'; +import './calculator.scss'; + +class Calculator extends Component { + constructor(props) { + super(props); + this.state = { + equation: '', + result: '', + }; + this.handleSubmit = this.handleSubmit.bind(this); + } + + async handleSubmit(event) { + event.preventDefault(); + event.stopPropagation(); + const urlEncoded = new URLSearchParams(); + urlEncoded.append('equation', this.state.equation); + + const response = await getAuthenticatedHttpClient().get( + `${getConfig().LMS_BASE_URL}/calculate?${urlEncoded.toString()}`, + ); + this.setState(() => ({ result: response.data.result })); + } + + changeEquation(value) { + this.setState(() => ({ equation: value })); + } + + render() { + return ( + +
+ + + + + + {this.props.intl.formatMessage(messages['calculator.button.label'])} + +
+ +
+ this.changeEquation(event.target.value)} + /> + + +
+ + +
+ + + + + + + +
+ + + + + ), + edx_guide: ( + + + + ), + }} + /> +

+ + + +

+
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + +
+ + +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+
+
    +
  • 2520
  • +
  • 2/3
  • +
  • 3.14, .98
  • +
+
+ + +
    +
  • + {' + - * / '} + +
  • +
  • + {'^ '} + +
  • +
  • + {'|| '} + +
  • +
+
+
    +
  • x+(2*y)/x-1
  • +
  • x^(n+1)
  • +
  • v_IN+v_OUT
  • +
  • 1||2
  • +
+
+ + c, e, g, i, j, k, pi, q, T +
    +
  • 20*c
  • +
  • 418*T
  • +
+
+ + + + +
    +
  • 20%
  • +
  • 20c
  • +
  • 418T
  • +
+
+ + abs, exp, fact, factorial, ln, log2, log10, sqrt +
    +
  • abs(x+y)
  • +
  • sqrt(x^2-y)
  • +
+
+ + +
    +
  • sin, cos, tan, sec, csc, cot
  • +
  • arcsin, sinh, arcsinh
  • +
+
+
    +
  • sin(4x+y)
  • +
  • arccsch(4x+y)
  • +
+
+
+ + + + 10^-9
+ + + + 1e-9
+
+
+
+
+ ); + } +} + +Calculator.propTypes = { + intl: intlShape.isRequired, +}; + + +export default injectIntl(Calculator); diff --git a/src/courseware/course/calculator/messages.js b/src/courseware/course/calculator/messages.js new file mode 100644 index 00000000..fe67b2a0 --- /dev/null +++ b/src/courseware/course/calculator/messages.js @@ -0,0 +1,31 @@ +import { defineMessages } from '@edx/frontend-platform/i18n'; + +const messages = defineMessages({ + 'calculator.button.label': { + id: 'calculator.button.label', + defaultMessage: 'Calculator', + description: 'Button label to expand or close the calculator', + }, + 'calculator.input.field.label': { + id: 'calculator.input.field.label', + defaultMessage: 'Calculator Input', + description: 'label for calculator input', + }, + 'calculator.submit.button.label': { + id: 'calculator.submit.button.label', + defaultMessage: 'Calculate', + description: 'Submit button label to execute the calculator', + }, + 'calculator.result.field.label': { + id: 'calculator.result.field.label', + defaultMessage: 'Calculator Result', + description: 'label for calculator result', + }, + 'calculator.result.field.placeholder': { + id: 'calculator.result.field.placeholder', + defaultMessage: 'Result', + description: 'placeholder for calculator result', + }, +}); + +export default messages; diff --git a/src/data/api.js b/src/data/api.js index 7de9e8ab..b563f755 100644 --- a/src/data/api.js +++ b/src/data/api.js @@ -19,6 +19,7 @@ function normalizeMetadata(metadata) { isStaff: metadata.user_has_staff_access, verifiedMode: camelCaseObject(metadata.verified_mode), tabs: camelCaseObject(metadata.tabs), + showCalculator: metadata.show_calculator, }; }