Skip to content
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

Instructions empty state #1165

Merged
merged 11 commits into from
Jan 16, 2025
Merged
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Autosave instructions
- Editable instructions
- Support for the `outputPanels` attribute in the `PyodideRunner` (#1157)
- Downloading project instructions (#116
- Downloading project instructions (#1160)
- Show instructions option in sidebar if instructions are editable (#1164)
- Open instructions panel by default if instructions are editable (#1164)
- Instructions empty state to show when instructions are editable (#1165)

### Changed

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"prismjs": "^1.29.0",
"prompts": "2.4.0",
"prop-types": "^15.8.1",
"raw-loader": "^4.0.2",
"rc-resize-observer": "^1.3.1",
"re-resizable": "6.9.9",
"react": "^18.1.0",
Expand Down
20 changes: 20 additions & 0 deletions src/assets/markdown/demoInstructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# How instructions work

## Enabling instructions

Any text written here will be visible to students in the sidebar

If you decide you do not want instructions, simply leave this panel blank.

## Writing instructions

Write your instructions using [Markdown](https://www.markdownguide.org/)
### What you can do

Lists:

- Bullet points
- Bullet points

1. numbered steps
2. numbered steps
13 changes: 13 additions & 0 deletions src/assets/stylesheets/Instructions.scss
Original file line number Diff line number Diff line change
Expand Up @@ -255,4 +255,17 @@
white-space: pre-wrap;
}
}

.project-instructions__empty {
background-color: $rpf-teal-100;
border-radius: $space-0-5;
display: flex;
flex-direction: column;
gap: $space-1-5;
padding: $space-1;
}

.project-instructions__empty-text {
margin: 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useMemo, useState } from "react";
import SidebarPanel from "../SidebarPanel";
import { useTranslation } from "react-i18next";
import { Trans, useTranslation } from "react-i18next";
import { useSelector, useDispatch } from "react-redux";
import ProgressBar from "./ProgressBar/ProgressBar";
import "../../../../assets/stylesheets/Instructions.scss";
Expand All @@ -10,7 +10,11 @@ import "prismjs/plugins/line-numbers/prism-line-numbers.css";
import "prismjs/plugins/line-highlight/prism-line-highlight.css";
import { quizReadyEvent } from "../../../../events/WebComponentCustomEvents";
import { setCurrentStepPosition } from "../../../../redux/InstructionsSlice";
import DesignSystemButton from "../../../DesignSystemButton/DesignSystemButton";
import { setProjectInstructions } from "../../../../redux/EditorSlice";
import demoInstructions from "../../../../assets/markdown/demoInstructions.md";
import { Link } from "react-router-dom";

const InstructionsPanel = () => {
const instructionsEditable = useSelector(
(state) => state.editor?.instructionsEditable,
Expand Down Expand Up @@ -61,9 +65,11 @@ const InstructionsPanel = () => {

useEffect(() => {
const setStepContent = (content) => {
stepContent.current.parentElement.scrollTo({ top: 0 });
stepContent.current.innerHTML = content;
applySyntaxHighlighting(stepContent.current);
if (stepContent.current) {
stepContent.current?.parentElement.scrollTo({ top: 0 });
stepContent.current.innerHTML = content;
applySyntaxHighlighting(stepContent.current);
}
};
if (isQuiz && !quizCompleted) {
setStepContent(quiz.questions[quiz.currentQuestion]);
Expand All @@ -90,6 +96,24 @@ const InstructionsPanel = () => {
}
}, [quizCompleted, currentStepPosition, numberOfSteps, dispatch, isQuiz]);

const addInstructions = () => {
dispatch(setProjectInstructions(demoInstructions));
};

const AddInstructionsButton = () => {
return (
<DesignSystemButton
className="btn--primary"
icon="add"
text={t("instructionsPanel.emptyState.addInstructions")}
onClick={addInstructions}
fill
textAlways
small
/>
);
};

const onChange = (e) => {
dispatch(setProjectInstructions(e.target.value));
};
Expand All @@ -98,18 +122,55 @@ const InstructionsPanel = () => {
<SidebarPanel
defaultWidth="30vw"
heading={t("instructionsPanel.projectSteps")}
Button={instructionsEditable && !hasInstructions && AddInstructionsButton}
{...{ Footer: hasMultipleSteps && ProgressBar }}
>
<div>
{instructionsEditable && (
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
<div className="project-instructions">
{instructionsEditable ? (
hasInstructions ? (
<div>
{instructionsEditable && (
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
)}
</div>
) : (
<div className="project-instructions__empty">
<p className="project-instructions__empty-text">
{t("instructionsPanel.emptyState.purpose")}
</p>
<p className="project-instructions__empty-text">
{t("instructionsPanel.emptyState.location")}
</p>
<p className="project-instructions__empty-text">
{() => (
<Trans
i18nKey="instructionsPanel.emptyState.markdown"
components={[
<Link
href="https://commonmark.org/help/"
target="_blank"
rel="noreferrer"
/>,
]}
/>
)}
</p>
<p className="project-instructions__empty-text">
{t("instructionsPanel.emptyState.edits")}
</p>
</div>
)
) : (
<div
className="project-instructions__content"
ref={stepContent}
></div>
)}
</div>
<div className="project-instructions" ref={stepContent}></div>
</SidebarPanel>
);
};
Expand Down
Loading
Loading