diff --git a/src/app/components/elements/list-groups/AbstractListViewItem.tsx b/src/app/components/elements/list-groups/AbstractListViewItem.tsx index 4636f0ae6d..e08a3b8cc7 100644 --- a/src/app/components/elements/list-groups/AbstractListViewItem.tsx +++ b/src/app/components/elements/list-groups/AbstractListViewItem.tsx @@ -103,7 +103,7 @@ export const AbstractListViewItem = ({icon, title, subject, subtitle, breadcrumb fullWidth = fullWidth || below["sm"](deviceSize) || ((status || audienceViews || previewQuizUrl || quizButton) ? false : true); const cardBody =
- +
{icon && ( icon.type === "img" ? diff --git a/src/app/components/elements/svg/DifficultyIcons.tsx b/src/app/components/elements/svg/DifficultyIcons.tsx index e15c9cabe3..b9502a1e75 100644 --- a/src/app/components/elements/svg/DifficultyIcons.tsx +++ b/src/app/components/elements/svg/DifficultyIcons.tsx @@ -5,6 +5,7 @@ import {difficultyLabelMap, difficultyShortLabelMap, isAda, isPhy, siteSpecific} import classnames from "classnames"; import {Rectangle} from "./Rectangle"; import {Circle} from "./Circle"; +import classNames from "classnames"; // Difficulty icon proportions const difficultyIconWidth = siteSpecific(15, 25); @@ -13,6 +14,8 @@ const yPadding = 2; const difficultyCategoryLevels = siteSpecific([1, 2, 3], [1, 2]); const miniHexagon = calculateHexagonProportions(difficultyIconWidth / 2, 0); const miniSquare = {width: difficultyIconWidth, height: difficultyIconWidth}; +const largeHexagon = calculateHexagonProportions(difficultyIconWidth, 0); +const largeSquare = {width: difficultyIconWidth * 2, height: difficultyIconWidth * 2}; const squareOffset = ((miniHexagon.quarterHeight * 4 + 2 * yPadding) - difficultyIconWidth) / 2 - 1; // ${yPadding + (difficultyCategory === "P" && isPhy ? 0 : 2)} @@ -21,16 +24,19 @@ interface DifficultyIconShapeProps { difficultyCategoryLevel: number; active: boolean; blank?: boolean; + size?: "sm" | "lg"; } -function SingleDifficultyIconShape({difficultyCategory, difficultyCategoryLevel, active, blank}: DifficultyIconShapeProps) { + +function SingleDifficultyIconShape({difficultyCategory, difficultyCategoryLevel, active, blank, size}: DifficultyIconShapeProps) { + const iconWidth = size === "lg" ? difficultyIconWidth * 2 : difficultyIconWidth; // FIXME the calculations here need refactoring, had to rush them to get it done - return + return {difficultyCategory === "P" ? siteSpecific( - , - + , + ) : - + } {/* {
@@ -64,3 +70,20 @@ export function DifficultyIcons({difficulty, blank, className} : {difficulty: Di
; } + +export function DifficultyIcon({difficultyCategory, className} : {difficultyCategory: string, className?: string}) { + return
+ + + +
; +} diff --git a/src/app/components/pages/SubjectLandingPage.tsx b/src/app/components/pages/SubjectLandingPage.tsx index cb171e4ef8..3dd94fcaec 100644 --- a/src/app/components/pages/SubjectLandingPage.tsx +++ b/src/app/components/pages/SubjectLandingPage.tsx @@ -93,7 +93,7 @@ export const LandingPageFooter = ({context}: {context: PageContextState}) => { // TODO: are we going to make subject-specific news? const {data: news} = useGetNewsPodListQuery({subject: "physics"}); - return + return
{/* if there are books, display books. otherwise, display news */} {books.length > 0 diff --git a/src/app/components/pages/SubjectOverviewPage.tsx b/src/app/components/pages/SubjectOverviewPage.tsx index cfa35d24fa..85e0a34a59 100644 --- a/src/app/components/pages/SubjectOverviewPage.tsx +++ b/src/app/components/pages/SubjectOverviewPage.tsx @@ -3,17 +3,21 @@ import { RouteComponentProps, withRouter } from "react-router"; import { Container } from "reactstrap"; import { TitleAndBreadcrumb } from "../elements/TitleAndBreadcrumb"; import { useUrlPageTheme } from "../../services/pageContext"; -import { HUMAN_SUBJECTS, isDefined, LEARNING_STAGE, LearningStage, PHY_NAV_SUBJECTS, Subject } from "../../services"; -import { PageContextState } from "../../../IsaacAppTypes"; -import { ListViewCards } from "../elements/list-groups/ListView"; +import { above, HUMAN_SUBJECTS, isDefined, LEARNING_STAGE, LearningStage, PHY_NAV_SUBJECTS, SEARCH_RESULT_TYPE, Subject, useDeviceSize } from "../../services"; +import { PageContextState, ShortcutResponse } from "../../../IsaacAppTypes"; +import { ListView, ListViewCardProps, ListViewCards } from "../elements/list-groups/ListView"; import { LandingPageFooter } from "./SubjectLandingPage"; +import { DifficultyIcon } from "../elements/svg/DifficultyIcons"; +import { AbstractListViewItemState } from "../elements/list-groups/AbstractListViewItem"; const SubjectCards = ({context}: { context: PageContextState }) => { + const deviceSize = useDeviceSize(); + if (!isDefined(context?.subject)) return null; const humanSubject = context?.subject && HUMAN_SUBJECTS[context.subject]; - return { }, url: `/${context.subject}/11_14`, stage: LEARNING_STAGE["11_TO_14"], + subject: context.subject, }, { item: { @@ -37,6 +42,8 @@ const SubjectCards = ({context}: { context: PageContextState }) => { }, url: `/${context.subject}/gcse`, stage: LEARNING_STAGE.GCSE, + subject: context.subject, + state: context.subject === "biology" ? AbstractListViewItemState.COMING_SOON : undefined, }, { item: { @@ -49,6 +56,7 @@ const SubjectCards = ({context}: { context: PageContextState }) => { }, url: `/${context.subject}/a_level`, stage: LEARNING_STAGE.A_LEVEL, + subject: context.subject, }, { item: { @@ -61,14 +69,43 @@ const SubjectCards = ({context}: { context: PageContextState }) => { }, url: `/${context.subject}/university`, stage: LEARNING_STAGE.UNIVERSITY, - } - ] - .map(({stage, ...card}) => (PHY_NAV_SUBJECTS[context.subject as Subject] as readonly LearningStage[])?.includes(stage) ? card : null) - .filter((x, i, a) => x || (i % 2 === 0 ? a[i + 1] : a[i - 1])) // remove pairs of nulls + subject: context.subject, + }, + ].map(({stage, ...card}) => (PHY_NAV_SUBJECTS[context.subject as Subject] as readonly LearningStage[])?.includes(stage) || card.state === AbstractListViewItemState.COMING_SOON ? card : null); + + return a ? (b ? 0 : -1) : 1) // put nulls at the end + .filter((x, i, a) => x || (i % 2 === 0 ? a[i + 1] : a[i - 1])) // remove pairs of nulls } />; }; +const ExampleQuestions = ({ subject, className }: { subject: Subject, className: string }) => { + const items: { [key in Subject]: ShortcutResponse[] } = { + maths: [{ + title: "Sample Maths Questions", + type: SEARCH_RESULT_TYPE.GAMEBOARD, + id: "sample_maths_questions", + }], + physics: [/*{ + title: "Sample Physics Questions", + type: SEARCH_RESULT_TYPE.GAMEBOARD, + id: "sample_phy_questions", + }*/], // Uncomment when physics questions are available + chemistry: [{ + title: "Sample Chemistry Questions", + type: SEARCH_RESULT_TYPE.GAMEBOARD, + id: "sample_chem_questions", + }], + biology: [{ + title: "Sample Biology Questions", + type: SEARCH_RESULT_TYPE.GAMEBOARD, + id: "sample_bio_questions", + }], + }; + + return items[subject].length > 0 ? : null; +}; + export const SubjectOverviewPage = withRouter((props: RouteComponentProps) => { const pageContext = useUrlPageTheme(); @@ -112,7 +149,20 @@ export const SubjectOverviewPage = withRouter((props: RouteComponentProps) => {

All Isaac Science questions are classed as either "Practice" or "Challenge" – indicated by the symbols below. +

+ +
+
+ + Practice +
+
+ + Challenge +
+
+

In Isaac {humanSubject},

  • Practice questions are those that require one concept or equation to solve.
  • @@ -120,7 +170,9 @@ export const SubjectOverviewPage = withRouter((props: RouteComponentProps) => {

- {/* */} +
+ +
} diff --git a/src/scss/phy/list-groups.scss b/src/scss/phy/list-groups.scss index 440ff5bc9a..d6bd529cbc 100644 --- a/src/scss/phy/list-groups.scss +++ b/src/scss/phy/list-groups.scss @@ -147,4 +147,9 @@ margin-left: 0.5rem; } } + + img { + // For items that use images rather than icons (e.g. subject logos), to remove the need to include a seperate greyscale image + filter: grayscale(100%); + } }