Skip to content

Commit

Permalink
initial home screen
Browse files Browse the repository at this point in the history
  • Loading branch information
eanders-ms committed Feb 11, 2024
1 parent 38ed80e commit 90f6def
Show file tree
Hide file tree
Showing 22 changed files with 366 additions and 26 deletions.
7 changes: 6 additions & 1 deletion teachertool/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,12 @@ export const App = () => {
await tryLoadLastActiveRubricAsync();

// Test notification
showToast(makeToast("success", "🎓", 2000));
showToast({
...makeToast("success", "🎓", 2000),
hideIcon: true,
hideDismissBtn: true,
textContainerClass: "app-large-toast",
});

setInited(true);
logDebug("App initialized");
Expand Down
22 changes: 20 additions & 2 deletions teachertool/src/components/HeaderBar.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import * as React from "react";
import { useContext } from "react";
// eslint-disable-next-line import/no-internal-modules
import css from "./styling/HeaderBar.module.scss";
import { Button } from "react-common/components/controls/Button";
import { MenuBar } from "react-common/components/controls/MenuBar";
import { AppStateContext } from "../state/appStateContext";
import { getSafeRubricName } from "../state/helpers";

interface HeaderBarProps {}

export const HeaderBar: React.FC<HeaderBarProps> = () => {
const { state: teacherTool } = useContext(AppStateContext);

const appTheme = pxt.appTarget?.appTheme;

const brandIconClick = () => {};
const brandIconClick = () => {
pxt.tickEvent("teachertool.brandicon");
// TODO: Link this
};

const getOrganizationLogo = () => {
return (
Expand Down Expand Up @@ -57,8 +65,17 @@ export const HeaderBar: React.FC<HeaderBarProps> = () => {
);
};

const getRubricName = (): JSX.Element | null => {
const rubricName = getSafeRubricName(teacherTool);
return rubricName ? (
<div className={css["rubric-name"]}>
<span>{rubricName}</span>
</div>
) : null;
};

const onHomeClicked = () => {
pxt.tickEvent("teacherTool.home");
pxt.tickEvent("teachertool.home");

// relprefix looks like "/beta---", need to chop off the hyphens and slash
let rel = pxt.webConfig?.relprefix.substr(0, pxt.webConfig.relprefix.length - 3);
Expand All @@ -77,6 +94,7 @@ export const HeaderBar: React.FC<HeaderBarProps> = () => {
<div className={css["left-menu"]}>
{getOrganizationLogo()}
{getTargetLogo()}
{getRubricName()}
</div>

<div className={css["right-menu"]}>
Expand Down
89 changes: 89 additions & 0 deletions teachertool/src/components/HomeScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import * as React from "react";
// eslint-disable-next-line import/no-internal-modules
import css from "./styling/HomeScreen.module.scss";
import { Link } from "react-common/components/controls/Link";
import { Button } from "react-common/components/controls/Button";
import { classList } from "react-common/components/util";
import { showModal } from "../transforms/showModal";
import { resetRubricAsync } from "../transforms/resetRubricAsync";

const Welcome: React.FC = () => {
return (
<div className={css.welcome}>
<h1>{lf("Welcome to MakeCode Project Insights!")}</h1>
<p>
{lf("This tool is designed to help you evaluate student projects using a rubric.")}{" "}
<Link target="_blank" href="https://makecode.com/teachertool">
{lf("Learn More.")}
</Link>
</p>
</div>
);
};

interface CardProps {
title: string;
className?: string;
icon?: string;
onClick: () => void;
}

const Card: React.FC<CardProps> = ({ title, className, icon, onClick }) => {
return (
<Button className={classList(css.cardButton, className)} title={title} onClick={onClick}>
<div className={css.cardDiv}>
{icon && (
<div className={css.cardIcon}>
<i className={icon}></i>
</div>
)}
<div className={css.cardTitle}>
<h3>{title}</h3>
</div>
</div>
</Button>
);
};

const GetStarted: React.FC = () => {
const onNewRubricClickedAsync = async () => {
pxt.tickEvent("teachertool.newrubric");
await resetRubricAsync(true);
};

const onImportRubricClicked = () => {
pxt.tickEvent("teachertool.importrubric");
showModal("import-rubric");
};

return (
<div className={css.getStarted}>
<h2>{lf("Get Started")}</h2>
{/* TODO: Replace with carousel */}
<div className={css.cards}>
<Card
title={lf("New Rubric")}
icon={"fas fa-plus-circle"}
className={css.newRubric}
onClick={onNewRubricClickedAsync}
/>
<Card
title={lf("Import Rubric")}
icon={"fas fa-file-upload"}
className={css.importRubric}
onClick={onImportRubricClicked}
/>
</div>
</div>
);
};

export const HomeScreen: React.FC = () => {
return (
<div className={css.page}>
<div className={css.top} />
<Welcome />
<GetStarted />
</div>
);
};
13 changes: 10 additions & 3 deletions teachertool/src/components/ProjectWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,23 @@ import * as React from "react";
// eslint-disable-next-line import/no-internal-modules
import css from "./styling/ProjectWorkspace.module.scss";

import { useContext } from "react";
import { AppStateContext } from "../state/appStateContext";
import { getSafeProjectName } from "../state/helpers";
import { Toolbar } from "./Toolbar";
import { ShareLinkInput } from "./ShareLinkInput";
import { MakeCodeFrame } from "./MakecodeFrame";

interface IProps {}
const ProjectName: React.FC = () => {
const { state: teacherTool } = useContext(AppStateContext);
const projectName = getSafeProjectName(teacherTool);
return projectName ? <div className={css.projectName}>{projectName}</div> : null;
};

export const ProjectWorkspace: React.FC<IProps> = () => {
export const ProjectWorkspace: React.FC = () => {
return (
<div className={css.panel}>
<Toolbar />
<Toolbar center={<ProjectName />} />
<ShareLinkInput />
<MakeCodeFrame />
</div>
Expand Down
29 changes: 19 additions & 10 deletions teachertool/src/components/RubricWorkspace.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { AppStateContext, stateAndDispatch } from "../state/appStateContext";
import { Toolbar } from "./Toolbar";
import { TabGroup, TabButton } from "./TabGroup";
import { TabPanel } from "./TabPanel";
import { HomeScreen } from "./HomeScreen";
import { EvalResultDisplay } from "./EvalResultDisplay";
import { ActiveRubricDisplay } from "./ActiveRubricDisplay";
import { MenuItem } from "react-common/components/controls/MenuDropdown";
Expand All @@ -15,28 +16,30 @@ import { runEvaluateAsync } from "../transforms/runEvaluateAsync";
import { writeRubricToFile } from "../services/fileSystemService";
import { showModal } from "../transforms/showModal";
import { isProjectLoaded } from "../state/helpers";
import { setActiveTab } from "../transforms/setActiveTab";
import { setAutorun } from "../transforms/setAutorun";

function handleImportRubricClicked() {
pxt.tickEvent("teachertool.importrubric");
showModal("import-rubric");
}

function handleExportRubricClicked() {
pxt.tickEvent("teachertool.exportrubric");
const { state: teacherTool } = stateAndDispatch();
writeRubricToFile(teacherTool.rubric);
}

async function handleEvaluateClickedAsync() {
setActiveTab("results");
await runEvaluateAsync();
pxt.tickEvent("teachertool.evaluate");
await runEvaluateAsync(true);
}

const WorkspaceTabButtons: React.FC = () => {
const { state: teacherTool } = useContext(AppStateContext);

return (
<TabGroup>
<TabButton name="home">{lf("Home")}</TabButton>
<TabButton name="rubric">{lf("Rubric")}</TabButton>
<TabButton name="results" disabled={!isProjectLoaded(teacherTool)}>
{lf("Results")}
Expand All @@ -48,6 +51,9 @@ const WorkspaceTabButtons: React.FC = () => {
const WorkspaceTabPanels: React.FC = () => {
return (
<>
<TabPanel name="home">
<HomeScreen />
</TabPanel>
<TabPanel name="rubric">
<ActiveRubricDisplay />
</TabPanel>
Expand All @@ -59,9 +65,11 @@ const WorkspaceTabPanels: React.FC = () => {
};

function getActionMenuItems(tab: TabName): MenuItem[] {
const items: MenuItem[] = [];
switch (tab) {
case "home":
case "rubric":
return [
items.push(
{
title: lf("Import Rubric"),
label: lf("Import Rubric"),
Expand All @@ -73,11 +81,13 @@ function getActionMenuItems(tab: TabName): MenuItem[] {
label: lf("Export Rubric"),
ariaLabel: lf("Export Rubric"),
onClick: handleExportRubricClicked,
},
];
}
);
break;
case "results":
return [];
break;
}
return items;
}

const WorkspaceToolbarButtons: React.FC = () => {
Expand All @@ -87,6 +97,7 @@ const WorkspaceToolbarButtons: React.FC = () => {
const actionItems = getActionMenuItems(activeTab);

const onAutorunChange = (checked: boolean) => {
pxt.tickEvent("teachertool.autorun", { checked: checked ? "true" : "false" });
setAutorun(checked);
};

Expand All @@ -108,9 +119,7 @@ const WorkspaceToolbarButtons: React.FC = () => {
);
};

interface IProps {}

export const RubricWorkspace: React.FC<IProps> = () => {
export const RubricWorkspace: React.FC = () => {
return (
<div className={css.panel}>
<Toolbar left={<WorkspaceTabButtons />} right={<WorkspaceToolbarButtons />} />
Expand Down
1 change: 1 addition & 0 deletions teachertool/src/components/ShareLinkInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ export const ShareLinkInput: React.FC<IProps> = () => {
onChange={onTextChange}
onEnterKey={onEnterKey}
preserveValueOnBlur={true}
autoComplete={false}
></Input>
</div>
);
Expand Down
4 changes: 2 additions & 2 deletions teachertool/src/components/Toasts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ const ToastNotification: React.FC<IToastNotificationProps> = ({ toast }) => {
{toast.icon ?? icons[toast.type]}
</div>
)}
<div className={css["text-container"]}>
{toast.text && <div className={css["text"]}>{toast.text}</div>}
<div className={classList(css["text-container"], "tt-toast-text-container", toast.textContainerClass)}>
{toast.text && <div className={classList(css["text"], "tt-toast-text")}>{toast.text}</div>}
{toast.detail && <div className={css["detail"]}>{toast.detail}</div>}
{toast.jsx && <div>{toast.jsx}</div>}
</div>
Expand Down
13 changes: 13 additions & 0 deletions teachertool/src/components/styling/HeaderBar.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,17 @@
margin: 0 1rem;
}
}

.rubric-name {
display: flex;
align-items: center;
&:before {
height: 1.5rem;
border-left: 2px solid var(--pxt-headerbar-foreground);
content: " ";
}
span {
margin: 0 1rem;
}
}
}
Loading

0 comments on commit 90f6def

Please sign in to comment.