diff --git a/src/components/CallToActionBanner.module.scss b/src/components/CallToActionBanner.module.scss new file mode 100644 index 00000000..fcf1f201 --- /dev/null +++ b/src/components/CallToActionBanner.module.scss @@ -0,0 +1,6 @@ +@import "~bootstrap/scss/_functions.scss"; +@import "~bootstrap/scss/_variables.scss"; + +.container { + background-color: $blue-700; +} diff --git a/src/components/DemoCourse.tsx b/src/components/CallToActionBanner.tsx similarity index 71% rename from src/components/DemoCourse.tsx rename to src/components/CallToActionBanner.tsx index 5cae3704..dcbb6deb 100644 --- a/src/components/DemoCourse.tsx +++ b/src/components/CallToActionBanner.tsx @@ -2,18 +2,20 @@ import React from "react"; import classnames from "classnames"; import Link from "next/link"; -import styles from "./Banner.module.scss"; +import styles from "./CallToActionBanner.module.scss"; -export interface DemoCourseCTAProps { +export interface BannerCTAProps { title: string; subtitle: string; buttonLabel: string; + href: string; } -export const DemoCourseCTA: React.FC = ({ +export const BannerCTA: React.FC = ({ title, subtitle, buttonLabel, + href, }) => (
@@ -25,10 +27,7 @@ export const DemoCourseCTA: React.FC = ({
- + {buttonLabel}
diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 808e75da..326f01dd 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -14,10 +14,12 @@ import { RequestCourseModal } from "../components/RequestCourseModal"; import styles from "./Header.module.scss"; -function useIsActive(href: string | string[]): boolean { +function useIsActive(href: string | string[], exact: boolean): boolean { const { asPath } = useRouter(); const hrefs = Array.isArray(href) ? href : [href]; - return hrefs.some((href) => asPath.startsWith(href)); + return hrefs.some((href) => + exact ? asPath === href : asPath.startsWith(href) + ); } function useIsCurrent(href: string): boolean { @@ -27,11 +29,12 @@ function useIsCurrent(href: string): boolean { interface NavLinkProps { href: string; + activeMatchExactHref?: boolean; children: React.ReactNode; } const RouterNavLink: React.FC = ({ href, children }) => { - const active = useIsActive(href); + const active = useIsActive(href, false); const current = useIsCurrent(href); return ( = ({ href, children }) => { ); }; -const NavDropdownItem: React.FC = ({ href, children }) => { - const active = useIsActive(href); +const NavDropdownItem: React.FC = ({ + href, + children, + activeMatchExactHref = false, +}) => { + const active = useIsActive(href, activeMatchExactHref); const current = useIsCurrent(href); return ( { + Product + + + + PrairieLearn + + + PrairieTest + + + Testing Centers + + + + + Catalog @@ -166,10 +197,10 @@ export const Header: React.FC = () => { About diff --git a/src/lib/images/byodinclass.png b/src/lib/images/byodinclass.png new file mode 100644 index 00000000..ed090ab4 Binary files /dev/null and b/src/lib/images/byodinclass.png differ diff --git a/src/lib/images/cbtf.jpg b/src/lib/images/cbtf.jpg new file mode 100644 index 00000000..cf132faa Binary files /dev/null and b/src/lib/images/cbtf.jpg differ diff --git a/src/lib/images/exam-management.png b/src/lib/images/exam-management.png new file mode 100644 index 00000000..436484da Binary files /dev/null and b/src/lib/images/exam-management.png differ diff --git a/src/lib/images/pt-reservation.png b/src/lib/images/pt-reservation.png new file mode 100644 index 00000000..e6c25128 Binary files /dev/null and b/src/lib/images/pt-reservation.png differ diff --git a/src/lib/images/reduced-distraction.png b/src/lib/images/reduced-distraction.png new file mode 100644 index 00000000..1f896591 Binary files /dev/null and b/src/lib/images/reduced-distraction.png differ diff --git a/src/lib/images/student-zoom.jpg b/src/lib/images/student-zoom.jpg new file mode 100644 index 00000000..7c9c51cc Binary files /dev/null and b/src/lib/images/student-zoom.jpg differ diff --git a/src/pages/about/index.tsx b/src/pages/about/index.tsx index a7d76409..96567287 100644 --- a/src/pages/about/index.tsx +++ b/src/pages/about/index.tsx @@ -1,10 +1,9 @@ import React from "react"; -import classnames from "classnames"; import Head from "next/head"; import Image, { ImageProps } from "next/image"; import { PageBanner } from "../../components/Banner"; -import { DemoCourseCTA } from "../../components/DemoCourse"; +import { BannerCTA } from "../../components/CallToActionBanner"; import { Heading } from "../../components/Heading"; import Stack from "../../components/Stack"; @@ -55,7 +54,7 @@ export default function About() { subtitle="We are passionate about teaching and strive to deliver the best course material to our students." /> -
+
@@ -182,10 +181,11 @@ export default function About() {
- ); diff --git a/src/pages/contact/index.tsx b/src/pages/contact/index.tsx index ca921d75..b09e8bdf 100644 --- a/src/pages/contact/index.tsx +++ b/src/pages/contact/index.tsx @@ -4,7 +4,7 @@ import classnames from "classnames"; import { ContactUsForm } from "../../components/ContactUsForm"; import { PageBanner } from "../../components/Banner"; -import { DemoCourseCTA } from "../../components/DemoCourse"; +import { BannerCTA } from "../../components/CallToActionBanner"; import styles from "./index.module.scss"; @@ -34,10 +34,11 @@ export default function Contact() {
- ); diff --git a/src/pages/gallery/assessments/index.tsx b/src/pages/gallery/assessments/index.tsx index 306c3620..06bcf86b 100644 --- a/src/pages/gallery/assessments/index.tsx +++ b/src/pages/gallery/assessments/index.tsx @@ -7,7 +7,7 @@ import Image from "next/image"; import { Heading } from "../../../components/Heading"; import { PageBanner } from "../../../components/Banner"; -import { DemoCourseCTA } from "../../../components/DemoCourse"; +import { BannerCTA } from "../../../components/CallToActionBanner"; import Stack from "../../../components/Stack"; import { getAssessments } from "../../../lib/gallery/assessments"; @@ -35,7 +35,7 @@ const AssessmentIndex: React.FC = ({ assessments }) => { subtitle="Building different types of activities for your class" /> -
+
@@ -87,10 +87,11 @@ const AssessmentIndex: React.FC = ({ assessments }) => {
- ); diff --git a/src/pages/gallery/courses/index.tsx b/src/pages/gallery/courses/index.tsx index 51af6948..893add52 100644 --- a/src/pages/gallery/courses/index.tsx +++ b/src/pages/gallery/courses/index.tsx @@ -2,7 +2,6 @@ import React from "react"; import Head from "next/head"; import Link from "next/link"; import Image, { ImageProps } from "next/image"; -import classnames from "classnames"; import { PageBanner } from "../../../components/Banner"; import { Heading } from "../../../components/Heading"; @@ -86,7 +85,7 @@ export default function Courses() { subtitle="Collections of assessments and questions" /> -
+
Course Catalog

@@ -256,7 +255,7 @@ export default function Courses() {

-
+

Contribute to this page

diff --git a/src/pages/gallery/questions/index.tsx b/src/pages/gallery/questions/index.tsx index d6223732..e096c5d1 100644 --- a/src/pages/gallery/questions/index.tsx +++ b/src/pages/gallery/questions/index.tsx @@ -7,7 +7,7 @@ import Image from "next/image"; import { Heading } from "../../../components/Heading"; import { PageBanner } from "../../../components/Banner"; -import { DemoCourseCTA } from "../../../components/DemoCourse"; +import { BannerCTA } from "../../../components/CallToActionBanner"; import { LinkButton } from "../../../components/LinkButton"; import { getQuestions } from "../../../lib/gallery/questions"; @@ -36,7 +36,7 @@ const GalleryIndex: React.FC = ({ questions }) => { subtitle="Create quality questions from a wide variety of input options" /> -

+
@@ -122,10 +122,11 @@ const GalleryIndex: React.FC = ({ questions }) => {
- ); diff --git a/src/pages/index.tsx b/src/pages/index.tsx index 6cc33067..c57d81bb 100644 --- a/src/pages/index.tsx +++ b/src/pages/index.tsx @@ -7,7 +7,7 @@ import Link from "next/link"; import Stack from "../components/Stack"; import { Heading } from "../components/Heading"; import { ExampleQuestion } from "../components/ExampleQuestion"; -import { DemoCourseCTA } from "../components/DemoCourse"; +import { BannerCTA } from "../components/CallToActionBanner"; import richFBD from "../lib/images/rich_question_FBD.png"; import richorder from "../lib/images/rich_question_order_block.png"; @@ -283,10 +283,11 @@ const Home: React.FC = ({ seed }) => {
- -
+
Question Templates

@@ -96,7 +95,7 @@ export default function Courses() {

-
+
-
+

License

diff --git a/src/pages/products/prairietest/index.module.scss b/src/pages/products/prairietest/index.module.scss new file mode 100644 index 00000000..9ef11251 --- /dev/null +++ b/src/pages/products/prairietest/index.module.scss @@ -0,0 +1,16 @@ +@import "~bootstrap/scss/_functions.scss"; +@import "~bootstrap/scss/_variables.scss"; + +.container { + background-color: $gray-200; +} + +.color { + color: $blue-700; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); + grid-gap: 2rem; +} diff --git a/src/pages/products/prairietest/index.tsx b/src/pages/products/prairietest/index.tsx new file mode 100644 index 00000000..02dec28d --- /dev/null +++ b/src/pages/products/prairietest/index.tsx @@ -0,0 +1,222 @@ +import React from "react"; +import Head from "next/head"; +import Image from "next/image"; +import classnames from "classnames"; + +import { PageBanner } from "../../../components/Banner"; +import { Heading } from "../../../components/Heading"; +import { BannerCTA } from "../../../components/CallToActionBanner"; + +import diagramImage from "../../../lib/images/exam-management.png"; +import schedulerImage from "../../../lib/images/pt-reservation.png"; +import onlineFormatImage from "../../../lib/images/student-zoom.jpg"; +import cbtfFormatImage from "../../../lib/images/cbtf.jpg"; +import byodFormatImage from "../../../lib/images/byodinclass.png"; + +import styles from "./index.module.scss"; + +interface FeatureCardProps { + icon?: React.ReactNode; + title: string; + children: React.ReactNode; +} + +const FeatureCard: React.FC = ({ icon, title, children }) => { + return ( +

+
{icon}
+
{title}
+ {children} +
+ ); +}; + +export default function PrairieTest() { + return ( + + + PrairieTest | PrairieLearn + + + +
+
+
+ Powerful exam management system +
+
+ diagram exam management process +
+
+
+ +
+
+
+

+ All exam management done in one place! +

+
+
+ } + title="Fast check-in process" + > + Supports card scanners providing fast student verification that + enables exams access. + + } + title="Accessible testing" + > + Ability to set up various exams accommodations, such as extended + exam time. + + } + title="Easy rescheduling" + > + Students are able to change their exam selection on their own + until the exam date. + + } + title="Per-student overrides" + > + Instructors can change exam settings for individual students. + + } + title="Proctoring assignments" + > + Instructors can assign proctors for the different sections of an + exam, or different exams. + + } + title="Unified scheduling view" + > + Students, proctors, and instructors can all see when and where + their exams are scheduled. + +
+
+
+ +
+
+
+ Student self-registration +

+ When instructors are running asynchronous exams, students are able + to select the time and location of their choice. They also have + the ability to change or cancel their reservation before the + scheduled exam, without having to contact the instructor. +

+
+
+ student scheduler UI +
+
+
+ +
+
+
+ Exams delivered in different formats +

+ PrairieTest can be used to deliver exams in multiple formats or in + a combination of any of them. +

+
+
+
+ students taking in-class exam +
+
+

Exams in the classroom

+

+ Students complete exams using their own device from a classroom, + or using institutional machines in a computer lab. In this + setup, course staff usually serve as proctors. +

+
+
+
+
+ student taking online exam +
+
+

Exams online

+

+ Students complete exams using their own device from a remote + location. In this setting, instructors can create virtual + meetings where students get their identification verified, and + access to the exam is provided via PrairieTest. +

+
+
+
+
+ testing center room +
+
+

Exams in testing centers

+

+ Students take their exams at a dedicated computer lab, which + runs asynchronous exams for many courses using trained proctors. + The testing center firewall blocks all access to the internet, + with the exception of allowed exam content. +

+
+
+
+
+ + +
+ ); +} diff --git a/src/pages/products/testing-center/index.module.scss b/src/pages/products/testing-center/index.module.scss new file mode 100644 index 00000000..7275f40b --- /dev/null +++ b/src/pages/products/testing-center/index.module.scss @@ -0,0 +1,12 @@ +@import "~bootstrap/scss/_functions.scss"; +@import "~bootstrap/scss/_variables.scss"; + +.container { + background-color: $gray-200; +} + +.grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(20rem, 1fr)); + grid-gap: 1rem; +} diff --git a/src/pages/products/testing-center/index.tsx b/src/pages/products/testing-center/index.tsx new file mode 100644 index 00000000..2d58beb3 --- /dev/null +++ b/src/pages/products/testing-center/index.tsx @@ -0,0 +1,198 @@ +import React from "react"; +import Head from "next/head"; +import Image from "next/image"; +import classnames from "classnames"; + +import { PageBanner } from "../../../components/Banner"; +import { Heading } from "../../../components/Heading"; +import { BannerCTA } from "../../../components/CallToActionBanner"; +import { LinkButton } from "../../../components/LinkButton"; + +import cbtfFormatImage from "../../../lib/images/cbtf.jpg"; +import reducedDistractionImage from "../../../lib/images/reduced-distraction.png"; + +import styles from "./index.module.scss"; + +interface ValuePropCardProps { + title: string; + children: React.ReactNode; +} + +const ValuePropCard: React.FC = ({ title, children }) => { + return ( +
+
+

{title}

+ {children} +
+
+ ); +}; + +export default function TestingCenter() { + return ( + + + Testing Centers | PrairieLearn + + + +
+
+
+
+
+ + What is a testing center? + +
+
+

+ A testing center is a dedicated room equipped with computers + and supervised by proctors, where students can take secure + computer-based exams. +

+
+ +
+
+ testing center +
+
+
+
+ +
+
+
+ + Benefits of a testing center + +
+
+ + Maximize exam integrity with managed computers, lab firewall, and + vigilant proctoring. Students access only approved resources, + while cheating risks are minimized through privacy screens, video + cameras, and professional oversight. + + + Ensure exam integrity by blocking access to AI services and + question-answering websites (such as ChatGPT, Copilot, Chegg, and + CourseHero), fostering academic honesty and fair assessment. + + + Ensure a fair and equitable experience for all students by using + professional proctors who are trained to uphold the testing center + policies and prevent violations. In addition, this relieves + instructors from proctoring duties, freeing course staff time for + other essential activities. + + + Enhance security measures by verifying students' identities + at the lab entrance through their student ID cards. In addition, + all personal belongings, including phones, are securely stored + before entering the testing environment. + + + Offer exams asynchronously over 2-3 days, optimizing space + utilization in smaller computer labs for larger classes. Eliminate + the need for instructors to manage make-up or conflict exams, + streamlining the exam process for both students and faculty. + + + Empower students, especially those balancing family and work + obligations, with the flexibility to schedule exams at their + preferred times within the exam period. Enable easy reservation + modifications and cancellations up to the selected exam time, + providing convenience and autonomy. + + + Empower instructors to effortlessly grant overrides for students + facing unexpected circumstances, such as illness or unavoidable + absences during the exam period. + + + Free up faculty time with a centralized testing center. From + scheduling to accommodations, the testing center handles exam + logistics efficiently, allowing faculty to focus on teaching and + student support. + + + Create an authentic testing environment by providing students with + access to compilers, debuggers, and graphical software, ensuring a + comprehensive assessment of their skills and knowledge. + + + Facilitate the accommodation process for students, ensuring they + have the support to take exams in the same environment as their + peers. Whether it's extended time or access to additional + resources, the process is simplified, promoting inclusivity and + equal opportunities. + +
+
+
+ +
+
+
+
+ seat in reduced distraction environment +
+
+
+ Academic accommodations +
+

+ Students with documented academic accommodations can take the + exams in the same setting as their classmates by using special + seats inside the testing center. A variety of common requests + can be accommodated: +

+
    +
  • Extended exam time
  • +
  • Reduced distraction environment
  • +
  • Text-to-speech software
  • +
  • + Accessible seating for students with wheelchairs or other + mobility needs +
  • +
  • Special arrangements for bathroom breaks
  • +
  • Access to disability related technology or equipment
  • +
  • Special/adjustable furniture
  • +
+
+
+
+
+ + +
+ ); +} diff --git a/src/pages/research/index.tsx b/src/pages/research/index.tsx index 6cc39d90..5329d374 100644 --- a/src/pages/research/index.tsx +++ b/src/pages/research/index.tsx @@ -3,7 +3,7 @@ import classnames from "classnames"; import Head from "next/head"; import { PageBanner } from "../../components/Banner"; -import { DemoCourseCTA } from "../../components/DemoCourse"; +import { BannerCTA } from "../../components/CallToActionBanner"; import { Heading } from "../../components/Heading"; import { ResearchCard } from "../../components/ResearchCard"; import Stack from "../../components/Stack"; @@ -565,10 +565,11 @@ export default function Research() {
- ); diff --git a/src/pages/sigcse2024-bof/index.tsx b/src/pages/sigcse2024-bof/index.tsx index 2e3cafe3..4bbca0c2 100644 --- a/src/pages/sigcse2024-bof/index.tsx +++ b/src/pages/sigcse2024-bof/index.tsx @@ -1,5 +1,4 @@ import React from "react"; -import classnames from "classnames"; import Head from "next/head"; import { PageBanner } from "../../components/Banner"; import { Heading } from "../../components/Heading"; @@ -17,7 +16,7 @@ export default function SIGCSE2024() { subtitle="Technical Symposium on Computer Science Education" /> -
+
BOF: Experiences With Computer-Based Testing diff --git a/src/pages/sigcse2024/index.tsx b/src/pages/sigcse2024/index.tsx index cf91f0f3..e31a2a68 100644 --- a/src/pages/sigcse2024/index.tsx +++ b/src/pages/sigcse2024/index.tsx @@ -1,5 +1,4 @@ import React from "react"; -import classnames from "classnames"; import Head from "next/head"; import Link from "next/link"; import { PageBanner } from "../../components/Banner"; @@ -18,7 +17,7 @@ export default function SIGCSE2024() { subtitle="Technical Symposium on Computer Science Education" /> -
+
@@ -56,7 +55,7 @@ export default function SIGCSE2024() { authoring these assessments.

-
+
-
+