| 89 | } |
| 90 | |
| 91 | export class Block extends Component<BlockProps, BlockState> { |
| 92 | static displayName: string; |
| 93 | constructor(props: BlockProps) { |
| 94 | super(props); |
| 95 | |
| 96 | this.state = { |
| 97 | showResetModal: false |
| 98 | }; |
| 99 | this.handleBlockClick = this.handleBlockClick.bind(this); |
| 100 | this.handleChallengeClick = this.handleChallengeClick.bind(this); |
| 101 | this.handleResetClick = this.handleResetClick.bind(this); |
| 102 | this.handleResetConfirm = this.handleResetConfirm.bind(this); |
| 103 | this.handleResetModalClose = this.handleResetModalClose.bind(this); |
| 104 | } |
| 105 | |
| 106 | handleBlockClick = (): void => { |
| 107 | const { block, toggleBlock } = this.props; |
| 108 | void playTone('block-toggle'); |
| 109 | toggleBlock(block); |
| 110 | }; |
| 111 | |
| 112 | handleChallengeClick = (): void => { |
| 113 | const { block } = this.props; |
| 114 | const dashedBlock = block |
| 115 | .toLowerCase() |
| 116 | .replace(/\s+/g, '-') |
| 117 | .replace(/[^a-z0-9-]/g, ''); |
| 118 | window.history.pushState(null, '', `#${dashedBlock}`); |
| 119 | }; |
| 120 | |
| 121 | handleResetClick = (): void => { |
| 122 | this.setState({ showResetModal: true }); |
| 123 | }; |
| 124 | |
| 125 | handleResetConfirm = (removedChallengeIds: string[]): void => { |
| 126 | const { removeModuleChallenges } = this.props; |
| 127 | removeModuleChallenges({ removedChallengeIds }); |
| 128 | }; |
| 129 | |
| 130 | handleResetModalClose = (): void => { |
| 131 | this.setState({ showResetModal: false }); |
| 132 | }; |
| 133 | |
| 134 | render(): ReactNode { |
| 135 | const { |
| 136 | block, |
| 137 | blockLabel, |
| 138 | completedChallengeIds, |
| 139 | challenges, |
| 140 | isExpanded: isExpandedProp, |
| 141 | superBlock, |
| 142 | t, |
| 143 | accordion = false, |
| 144 | expandAll = false |
| 145 | } = this.props; |
| 146 | |
| 147 | const isExpanded = expandAll || isExpandedProp; |
| 148 |
nothing calls this directly
no test coverage detected