Skip to content

Commit

Permalink
Instructions empty state (#1165)
Browse files Browse the repository at this point in the history
  • Loading branch information
loiswells97 authored and conorriches committed Jan 16, 2025
1 parent e8b547d commit ade61b2
Show file tree
Hide file tree
Showing 10 changed files with 426 additions and 218 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Show instructions option in sidebar if instructions are editable (#1164)
- Open instructions panel by default if instructions are editable (#1164)
- Downloading project instructions (#1160)
- 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;
}
}
126 changes: 94 additions & 32 deletions src/components/Menus/Sidebar/InstructionsPanel/InstructionsPanel.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
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 { Tabs, TabList, Tab, TabPanel } from "react-tabs";
import { Link } from "react-router-dom";

import ProgressBar from "./ProgressBar/ProgressBar";
import "../../../../assets/stylesheets/Instructions.scss";
Expand All @@ -12,7 +13,9 @@ 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";

const InstructionsPanel = () => {
const instructionsEditable = useSelector(
Expand Down Expand Up @@ -65,11 +68,11 @@ const InstructionsPanel = () => {

useEffect(() => {
const setStepContent = (content) => {
if (!stepContent?.current) return;

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 Down Expand Up @@ -97,6 +100,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 @@ -105,34 +126,75 @@ const InstructionsPanel = () => {
<SidebarPanel
defaultWidth="30vw"
heading={t("instructionsPanel.projectSteps")}
Button={instructionsEditable && !hasInstructions && AddInstructionsButton}
{...{ Footer: hasMultipleSteps && ProgressBar }}
>
{instructionsEditable ? (
<Tabs
onSelect={(index) => {
setInstructionsTab(index);
}}
>
<TabList>
<Tab>{t("instructionsPanel.edit")}</Tab>
<Tab>{t("instructionsPanel.view")}</Tab>
</TabList>
<TabPanel>
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
</TabPanel>
<TabPanel>
<>
<div className="project-instructions" ref={stepContent}></div>
</>
</TabPanel>
</Tabs>
) : (
<div className="project-instructions" ref={stepContent}></div>
)}
<div className="project-instructions">
{instructionsEditable ? (
hasInstructions ? (
<div>
{instructionsEditable && (
<Tabs
onSelect={(index) => {
setInstructionsTab(index);
}}
>
<TabList>
<Tab>{t("instructionsPanel.edit")}</Tab>
<Tab>{t("instructionsPanel.view")}</Tab>
</TabList>
<TabPanel>
<textarea
data-testid="instructionTextarea"
value={project.instructions}
onChange={onChange}
></textarea>
</TabPanel>
<TabPanel>
<>
<div
className="project-instructions"
ref={stepContent}
></div>
</>
</TabPanel>
</Tabs>
)}
</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>
</SidebarPanel>
);
};
Expand Down
Loading

0 comments on commit ade61b2

Please sign in to comment.