From 932e2f20e0a3fd69abd32b9f1786163997fd1204 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Tue, 9 Jul 2024 12:32:30 +0100 Subject: [PATCH 01/44] create custom heading components for react-markdown --- components/content/Content.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/components/content/Content.tsx b/components/content/Content.tsx index 82614ad6..b9324322 100644 --- a/components/content/Content.tsx +++ b/components/content/Content.tsx @@ -20,7 +20,7 @@ import Solution from "./Solution" import { first } from "cypress/types/lodash" import remarkDirective from "remark-directive" import remarkDirectiveRehype from "remark-directive-rehype" -import { CodeComponent, CodeProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" +import { CodeComponent, CodeProps, HeadingProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" import Callout from "../Callout" import { Course, Section, Theme } from "lib/material" import Paragraph from "./Paragraph" @@ -56,6 +56,13 @@ const list = (sectionStr: string) => { return list } +const heading = (sectionStr: string, tag: string) => { + function heading({ node, children, ...props }: HeadingProps) { + return + } + return heading +} + let solutionCount = 0 function solution({ node, children, ...props }: ReactMarkdownProps) { solutionCount++ @@ -161,6 +168,8 @@ const Content: React.FC = ({ markdown, theme, course, section }) => { code, p: p(sectionStr), li: list(sectionStr), + h2: heading(sectionStr, "h2"), + h3: heading(sectionStr, "h3"), }} > {markdown} From 48904f184aff435169b1b436d538c285fe05faa1 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Tue, 9 Jul 2024 12:35:31 +0100 Subject: [PATCH 02/44] return variable instead of

--- components/content/Paragraph.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index e64d2343..1ccec08a 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -20,9 +20,10 @@ const as = nlp.as interface ParagraphProps { content: React.ReactNode section: string + tag: string } -const Paragraph: React.FC = ({ content, section }) => { +const Paragraph: React.FC = ({ content, section, tag = "p" }) => { const ref = useRef(null) const [activeEvent, setActiveEvent] = useActiveEvent() const { commentThreads, error, isLoading, mutate } = useCommentThreads(activeEvent?.id) @@ -30,6 +31,7 @@ const Paragraph: React.FC = ({ content, section }) => { const [tempThread, setTempThread] = useState(undefined) const [tempActive, setTempActive] = useState(false) const email = useSession().data?.user?.email + const Tag = tag as keyof JSX.IntrinsicElements const { similarThreads, contentText } = useMemo(() => { let contentText = "" @@ -136,7 +138,7 @@ const Paragraph: React.FC = ({ content, section }) => { return ( <>

-

{content}

+ {content} {activeEvent && (
From db718f2f214ebe8273db4cff0be983657eec3ae4 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Tue, 9 Jul 2024 12:37:01 +0100 Subject: [PATCH 03/44] add tag parameter to p and list react-markdown components --- components/content/Content.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/content/Content.tsx b/components/content/Content.tsx index b9324322..01d75b28 100644 --- a/components/content/Content.tsx +++ b/components/content/Content.tsx @@ -40,7 +40,7 @@ function reactMarkdownRemarkDirective() { const p = (sectionStr: string) => { function p({ node, children, ...props }: ReactMarkdownProps) { - return + return } return p } @@ -49,7 +49,7 @@ const list = (sectionStr: string) => { function list({ node, children, ...props }: ReactMarkdownProps) { return (
  • - +
  • ) } @@ -58,7 +58,7 @@ const list = (sectionStr: string) => { const heading = (sectionStr: string, tag: string) => { function heading({ node, children, ...props }: HeadingProps) { - return + return } return heading } From a757c52da3810f0e6ed4e144648eb803282c7b7f Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Tue, 9 Jul 2024 12:41:14 +0100 Subject: [PATCH 04/44] replaceAll not replace --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 1ccec08a..344a06ed 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -138,7 +138,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => return ( <>
    - {content} + {content} {activeEvent && (
    From 1acd3163de3dc2b9cf5b4eec935fc1585ce3b6b9 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Tue, 9 Jul 2024 14:57:29 +0100 Subject: [PATCH 05/44] style headings differently --- components/content/Paragraph.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 344a06ed..d337b38b 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -137,8 +137,13 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => return ( <> -
    - {content} +
    + + {content} + {activeEvent && (
    From 56373a7a7d473068078f9fd5e34d2f3e196fda28 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Wed, 10 Jul 2024 14:57:36 +0100 Subject: [PATCH 06/44] return separate

    and jsx --- components/content/Paragraph.tsx | 46 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index d337b38b..f4b300ac 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -135,15 +135,10 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => } } - return ( - <> -

    - - {content} - + return tag === "p" ? ( + <> +
    +

    {content}

    {activeEvent && (
    @@ -175,6 +170,39 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) =>
    {activeEvent && } + ) : ( + <> + {content} + {activeEvent && ( +
    +
    + {similarThreads?.map((thread) => ( + + active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) + } + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + handleDeleteThread(tempThread)} + /> + )} +
    +
    + )} + {activeEvent && } + ) } From 30ad5852975678dccd91c541a163a85c6bc2e3ad Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Wed, 10 Jul 2024 15:03:14 +0100 Subject: [PATCH 07/44] upper case IDs --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index f4b300ac..3bd323ba 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -172,7 +172,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => ) : ( <> - {content} + {content} {activeEvent && (
    From 32b59d04ab399085c0dc3e67557059728883333e Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Wed, 10 Jul 2024 15:43:56 +0100 Subject: [PATCH 08/44] prettier --- components/content/Paragraph.tsx | 58 +++++++++++++++----------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 3bd323ba..d5f54d29 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -136,7 +136,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => } return tag === "p" ? ( - <> + <>

    {content}

    {activeEvent && ( @@ -172,36 +172,34 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => ) : ( <> - {content} - {activeEvent && ( -
    -
    - {similarThreads?.map((thread) => ( - - active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) - } - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(thread)} - /> - ))} - {tempThread && ( - handleDeleteThread(tempThread)} - /> - )} -
    + {content} + {activeEvent && ( +
    +
    + {similarThreads?.map((thread) => ( + (active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined))} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + handleDeleteThread(tempThread)} + /> + )}
    - )} - {activeEvent && } +
    + )} + {activeEvent && } ) } From bfa724f914808217d5d0f09664e16a09ceb29ee2 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Thu, 11 Jul 2024 10:25:25 +0100 Subject: [PATCH 09/44] tag param optional, default

    --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index d5f54d29..2e57e174 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -20,7 +20,7 @@ const as = nlp.as interface ParagraphProps { content: React.ReactNode section: string - tag: string + tag?: string } const Paragraph: React.FC = ({ content, section, tag = "p" }) => { From 88bbd72585af9c23b013650040341f25bc33c179 Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Thu, 11 Jul 2024 14:56:40 +0100 Subject: [PATCH 10/44] fixed comment position for headings --- components/content/Paragraph.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 2e57e174..88d46cc5 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -171,7 +171,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => {activeEvent && } ) : ( - <> +

    {content} {activeEvent && (
    @@ -200,7 +200,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) =>
    )} {activeEvent && } - +
    ) } From 67b75a15137f097a04199308f7b43556d30fc204 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <10367135+dankimberley@users.noreply.github.com> Date: Thu, 11 Jul 2024 15:20:49 +0100 Subject: [PATCH 11/44] Mobile and narrow-resolution improvements (#235) * render navbar only if window is wider than breakpoint * render (non-functional) burger menu below breakpoint * classes * implement useWindowSize hook * fixed toolbar elements staying on the right * fixed licensing button moving when nav bar condenses * maintain padding at narrow resolutions * burger menu click open drawer * added functional but unstyled burger draw * basic styling * present material themes in one column when window width less than columnBreakpoint * added padding to 'material themes' title * footer condenses awkwardly below media breakpoint, changed to flex below md: for better themebutton positioning * fixed ThemeSwitcher positioning in flex div * minor footer placement fix * added burger drawer material indentation * burger drawer styling improvements * add dark mode to burger drawer * add dark mode to burger drawer (and run prettify on footer.tsx) --- components/Footer.tsx | 13 +- components/Navbar.tsx | 430 +++++++++++++++++++++----------- components/ThemeCards.tsx | 5 +- components/content/Content.tsx | 2 +- components/ui/ThemeSwitcher.tsx | 2 +- pages/material/index.tsx | 2 +- 6 files changed, 296 insertions(+), 158 deletions(-) diff --git a/components/Footer.tsx b/components/Footer.tsx index fa578a55..49d7b2cc 100644 --- a/components/Footer.tsx +++ b/components/Footer.tsx @@ -12,14 +12,17 @@ interface Props { const Footer: React.FC = ({ pageInfo }) => { const footerAttrib = pageInfo?.footer return ( -
    +
    {footerAttrib && } -

    - For attribution and license information click the @ symbol on the top right -

    - + +
    +

    + For attribution and license information click the @ symbol on the top right +

    + +
    ) } diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 958f828f..28c51f2c 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -11,6 +11,12 @@ import { useRecoilState } from "recoil" import { enableSearch } from "lib/search/enableSearch" import NavDiagramPopover from "./dialogs/navDiagramPop" import ThemeCardsPopover from "./dialogs/themeCardPop" +import { Divider, IconButton } from "@mui/material" +import MenuIcon from "@mui/icons-material/Menu" +import Drawer from "@mui/material/Drawer" +import CloseIcon from "@mui/icons-material/Close" +import Box from "@mui/material/Box" +import useWindowSize from "lib/hooks/useWindowSize" interface Props { material: Material @@ -44,6 +50,12 @@ const Navbar: React.FC = ({ const [isPopoverHovered, setIsPopoverHovered] = useState(false) const [isHovered, setIsHovered] = useState(false) const [itemHovered, setItemHovered] = useState("") + const [width, setWidth] = useState(0) + const [menu, setMenu] = useState(false) + const [drawerOpen, setDrawerOpen] = useState(false) + const windowSize = useWindowSize() + const breakpoint = 900 + const burgerDrawerMaterialMargin = "ml-9" const { data: session } = useSession() const ref1 = useRef(null) const ref2 = useRef(null) @@ -106,164 +118,284 @@ const Navbar: React.FC = ({ setIsPopoverHovered(false) } + const toggleDrawer = (open: boolean) => { + setDrawerOpen(open) + } + return ( -
    - + ) : ( +
    + toggleDrawer(true)} + size="large" + edge="start" + color="inherit" + aria-label="menu" + className="text-gray-400 ml-1" + sx={{ mr: 2 }} + > + + + + + toggleDrawer(false)} sx={{ p: 2 }}> + + +
      +
    1. + + + + + Home + +
    2. + {theme && ( +
        +
      1. +
        + + + + + Material + +
        +
      2. +
      3. + +
      4. +
      )} -
    - - )}{" "} - {theme && course && ( -
  • handleIsHovered("section")} onMouseLeave={handleIsNotHovered}> -
    - - - - - {course.name} - - {showNavDiagram && itemHovered === "section" && ( - + {theme && ( +
  • handleIsHovered("course")} onMouseLeave={handleIsNotHovered}> +
    + + {theme.name} + +
    +
  • + )}{" "} + {theme && course && ( +
  • +
    + + {course.name} + +
    +
  • + )}{" "} + {section && ( +
  • +
    + + {section.name} + +
    +
  • )} -
    - - )}{" "} - {section && ( -
  • -
    - - - - - {section.name} - -
    -
  • - )} - - -
      + + + +
    + )} +
      {theme && course && section && (
    • = ({ )}
    • -
    • +
    • diff --git a/pages/material/index.tsx b/pages/material/index.tsx index 0d5929c2..8e89f396 100644 --- a/pages/material/index.tsx +++ b/pages/material/index.tsx @@ -17,7 +17,7 @@ type HomeProps = { const Home: NextPage = ({ material, events, pageInfo }) => { return ( -

      Material Themes

      +

      Material Themes

      ) From 2d32b79c694116544d0e7ac43049f6370acd8fec Mon Sep 17 00:00:00 2001 From: Dan Kimberley Date: Thu, 11 Jul 2024 15:20:54 +0100 Subject: [PATCH 12/44] added copy button, broken heading comment position --- components/content/Paragraph.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 88d46cc5..1c20e187 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -12,6 +12,8 @@ import useActiveEvent from "lib/hooks/useActiveEvents" import { Comment } from "pages/api/comment/[commentId]" import { CommentThread } from "pages/api/commentThread" import { useSession } from "next-auth/react" +import CopyToClipboard from "react-copy-to-clipboard" +import { FaClipboard } from "react-icons/fa" const nlp = winkNLP(model) const its = nlp.its @@ -171,8 +173,16 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) => {activeEvent && } ) : ( -
      - {content} + <> + + {content}{" "} + + + + {activeEvent && (
      @@ -200,7 +210,7 @@ const Paragraph: React.FC = ({ content, section, tag = "p" }) =>
      )} {activeEvent && } -
      + ) } From 62d2acdec63ef923d4cba5b0a9bd177ca27afa79 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson Date: Thu, 30 May 2024 13:25:57 +0100 Subject: [PATCH 13/44] move nav diagram into folder --- components/dialogs/navDiagramPop.tsx | 2 +- components/{ => navdiagram}/NavDiagram.tsx | 0 components/{ => navdiagram}/NavDiagramCourseNode.tsx | 0 components/{ => navdiagram}/NavDiagramSectionNode.tsx | 0 components/{ => navdiagram}/NavDiagramThemeNode.tsx | 0 lib/material.ts | 10 ++++++++-- pages/event/[eventId].tsx | 2 +- pages/event/[eventId]/[eventGroupId].tsx | 1 + pages/material/[repoId]/[themeId].tsx | 2 +- pages/material/[repoId]/[themeId]/[courseId].tsx | 2 +- 10 files changed, 13 insertions(+), 6 deletions(-) rename components/{ => navdiagram}/NavDiagram.tsx (100%) rename components/{ => navdiagram}/NavDiagramCourseNode.tsx (100%) rename components/{ => navdiagram}/NavDiagramSectionNode.tsx (100%) rename components/{ => navdiagram}/NavDiagramThemeNode.tsx (100%) diff --git a/components/dialogs/navDiagramPop.tsx b/components/dialogs/navDiagramPop.tsx index 4e6d93a7..aeff8567 100644 --- a/components/dialogs/navDiagramPop.tsx +++ b/components/dialogs/navDiagramPop.tsx @@ -1,4 +1,4 @@ -import NavDiagram from "components/NavDiagram" +import NavDiagram from "components/navdiagram/NavDiagram" import React, { useEffect, useState } from "react" import { createPortal } from "react-dom" import { Material, Theme, Course, Excludes } from "lib/material" diff --git a/components/NavDiagram.tsx b/components/navdiagram/NavDiagram.tsx similarity index 100% rename from components/NavDiagram.tsx rename to components/navdiagram/NavDiagram.tsx diff --git a/components/NavDiagramCourseNode.tsx b/components/navdiagram/NavDiagramCourseNode.tsx similarity index 100% rename from components/NavDiagramCourseNode.tsx rename to components/navdiagram/NavDiagramCourseNode.tsx diff --git a/components/NavDiagramSectionNode.tsx b/components/navdiagram/NavDiagramSectionNode.tsx similarity index 100% rename from components/NavDiagramSectionNode.tsx rename to components/navdiagram/NavDiagramSectionNode.tsx diff --git a/components/NavDiagramThemeNode.tsx b/components/navdiagram/NavDiagramThemeNode.tsx similarity index 100% rename from components/NavDiagramThemeNode.tsx rename to components/navdiagram/NavDiagramThemeNode.tsx diff --git a/lib/material.ts b/lib/material.ts index e06b94b3..980115b0 100644 --- a/lib/material.ts +++ b/lib/material.ts @@ -231,11 +231,17 @@ export async function getCourse(repo: string, theme: string, course: string, no_ const dependsOn = (courseObject.attributes.dependsOn as string[]) || [] const markdown = no_markdown ? "" : (courseObject.body as string) // @ts-expect-error - const files = courseObject.attributes.files as [string] + let files = courseObject.attributes.files as string[][] | string[] + if (typeof files[0] === "string") { + files = [files] as string[][] + } else { + files = files as string[][] + } + console.log(files.flatMap((x) => x)) // @ts-expect-error const attribution = (courseObject.attributes.attribution as Attribution[]) || [] const id = course - let sections = await Promise.all(files.map((file, i) => getSection(repo, theme, course, i, file))) + let sections = await Promise.all(files.flatMap((x) => x).map((file, i) => getSection(repo, theme, course, i, file))) const excludeSections = getExcludes(repo).sections sections = sections.filter((section) => !excludeSections.includes(section.id)) const type = "Course" diff --git a/pages/event/[eventId].tsx b/pages/event/[eventId].tsx index ead30a25..c6c34758 100644 --- a/pages/event/[eventId].tsx +++ b/pages/event/[eventId].tsx @@ -4,7 +4,7 @@ import { getMaterial, Theme, Material, removeMarkdown } from "lib/material" import Layout from "components/Layout" import { makeSerializable } from "lib/utils" import Content from "components/content/Content" -import NavDiagram from "components/NavDiagram" +import NavDiagram from "components/navdiagram/NavDiagram" import Title from "components/ui/Title" import type { Event, EventFull } from "lib/types" import { basePath } from "lib/basePath" diff --git a/pages/event/[eventId]/[eventGroupId].tsx b/pages/event/[eventId]/[eventGroupId].tsx index 31691562..fda778cc 100644 --- a/pages/event/[eventId]/[eventGroupId].tsx +++ b/pages/event/[eventId]/[eventGroupId].tsx @@ -5,6 +5,7 @@ import { getMaterial, Theme, Material, removeMarkdown, eventItemSplit } from "li import Layout from "components/Layout" import { makeSerializable } from "lib/utils" import Content from "components/content/Content" +import NavDiagram from "components/navdiagram/NavDiagram" import Title from "components/ui/Title" import SubTitle from "components/ui/SubTitle" import { Event } from "lib/types" diff --git a/pages/material/[repoId]/[themeId].tsx b/pages/material/[repoId]/[themeId].tsx index f8d77f4c..88e4bb6c 100644 --- a/pages/material/[repoId]/[themeId].tsx +++ b/pages/material/[repoId]/[themeId].tsx @@ -4,7 +4,7 @@ import { getMaterial, Theme, Material, removeMarkdown, getExcludes, Excludes } f import Layout from "components/Layout" import { makeSerializable } from "lib/utils" import Content from "components/content/Content" -import NavDiagram from "components/NavDiagram" +import NavDiagram from "components/navdiagram/NavDiagram" import Title from "components/ui/Title" import { Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" diff --git a/pages/material/[repoId]/[themeId]/[courseId].tsx b/pages/material/[repoId]/[themeId]/[courseId].tsx index 4730521f..de6a6427 100644 --- a/pages/material/[repoId]/[themeId]/[courseId].tsx +++ b/pages/material/[repoId]/[themeId]/[courseId].tsx @@ -4,7 +4,7 @@ import { getMaterial, Course, Theme, Material, removeMarkdown } from "lib/materi import Layout from "components/Layout" import { makeSerializable } from "lib/utils" import Content from "components/content/Content" -import NavDiagram from "components/NavDiagram" +import NavDiagram from "components/navdiagram/NavDiagram" import Title from "components/ui/Title" import { Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" From 342c9ce07c8df6031662a0c42baee5b3f54a36ae Mon Sep 17 00:00:00 2001 From: Alasdair Wilson Date: Mon, 3 Jun 2024 15:06:19 +0100 Subject: [PATCH 14/44] refactor: Add className and style props to SubTitle, Title, and Stack components --- components/ui/Stack.tsx | 7 +++++-- components/ui/SubTitle.tsx | 3 ++- components/ui/Title.tsx | 4 +++- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/components/ui/Stack.tsx b/components/ui/Stack.tsx index 33925999..3b16ae33 100644 --- a/components/ui/Stack.tsx +++ b/components/ui/Stack.tsx @@ -5,9 +5,10 @@ interface StackProps { children: ReactNode direction?: "row" | "col" | "row-reverse" | "col-reverse" | undefined className?: React.ComponentProps<"div">["className"] + style?: React.ComponentProps<"div">["style"] } -function Stack({ spacing = 4, children, direction, className }: StackProps) { +function Stack({ spacing = 4, children, direction, className, style }: StackProps) { if (direction === undefined) { direction = "col" } @@ -34,7 +35,9 @@ function Stack({ spacing = 4, children, direction, className }: StackProps) { const axis = direction.includes("col") ? "col" : "row" return ( -
      {children}
      +
      + {children} +
      ) } diff --git a/components/ui/SubTitle.tsx b/components/ui/SubTitle.tsx index da3448f9..ecbf0261 100644 --- a/components/ui/SubTitle.tsx +++ b/components/ui/SubTitle.tsx @@ -2,10 +2,11 @@ import React from "react" type Props = { text: string + className?: string } const SubTitle: React.FC = (props) => { - return

      {props.text}

      + return

      {props.text}

      } export default SubTitle diff --git a/components/ui/Title.tsx b/components/ui/Title.tsx index 311ffb23..4e802de0 100644 --- a/components/ui/Title.tsx +++ b/components/ui/Title.tsx @@ -2,11 +2,13 @@ import React from "react" type Props = { text: string + className?: string + style?: React.CSSProperties } const Header: React.FC = (props) => { return ( -

      +

      {props.text}

      ) From 39af11cc4f72b053132179b6bdaeb87eb7d7bd37 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson Date: Mon, 3 Jun 2024 15:07:39 +0100 Subject: [PATCH 15/44] feat: Add CourseGrid component and update Course layout The code changes include adding the `CourseGrid` component to to use a mui grid rather than the react-flow diagram --- components/navdiagram/CourseGrid.tsx | 66 ++++++++++++++ .../[repoId]/[themeId]/[courseId].tsx | 11 ++- .../[repoId]/[themeId]/[courseId]/diagram.tsx | 85 +++++++++++++++++++ 3 files changed, 160 insertions(+), 2 deletions(-) create mode 100644 components/navdiagram/CourseGrid.tsx create mode 100644 pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx diff --git a/components/navdiagram/CourseGrid.tsx b/components/navdiagram/CourseGrid.tsx new file mode 100644 index 00000000..5ee76c03 --- /dev/null +++ b/components/navdiagram/CourseGrid.tsx @@ -0,0 +1,66 @@ +import React from "react" +import Link from "next/link" +import { Grid, Paper, Typography, Box } from "@mui/material" +import { Course, Theme } from "lib/material" +import { useTheme } from "next-themes" + +function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { + const files = course.files + + const findSectionByName = (fileName: string) => { + return course.sections.find((section) => section.file === fileName) + } + const repo = theme.repo + + const findCommonTag = (column: string[]) => { + const tagsArray = column.map((file) => { + const section = findSectionByName(file) + return section ? section.tags : [] + }) + if (tagsArray.length === 0) return null + + const commonTags = tagsArray.reduce((a, b) => a.filter((c) => b.includes(c))) + return commonTags.length > 0 ? commonTags[0] : null // returns the first common tag if any + } + + return ( +
      + + {files.map((column, colIndex) => { + const commonTag = findCommonTag(column) + return ( + + {commonTag && ( + + {commonTag.toUpperCase()} + + )} + + {column.map((file, rowIndex) => { + const section = findSectionByName(file) + if (!section) return null + const url = `/material/${repo}/${course.theme}/${course.id}/${section.id}` + console.log(url) + return ( + + + + {section ? section.name : "Unnamed Section"} + + + + ) + })} + + + ) + })} + +
      + ) +} + +export default CourseGrid diff --git a/pages/material/[repoId]/[themeId]/[courseId].tsx b/pages/material/[repoId]/[themeId]/[courseId].tsx index de6a6427..77c13ffb 100644 --- a/pages/material/[repoId]/[themeId]/[courseId].tsx +++ b/pages/material/[repoId]/[themeId]/[courseId].tsx @@ -9,6 +9,10 @@ import Title from "components/ui/Title" import { Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" import revalidateTimeout from "lib/revalidateTimeout" +import CourseGrid from "components/navdiagram/CourseGrid" +import Stack from "components/ui/Stack" +import Link from "next/link" +import SubTitle from "components/ui/SubTitle" type CourseComponentProps = { theme: Theme @@ -27,8 +31,11 @@ const CourseComponent: NextPage = ({ }: CourseComponentProps) => { return ( - - <NavDiagram material={material} theme={theme} course={course} /> + <Title text={course.name} style={{ marginBottom: "0px" }} /> + <Link className="text-blue-500 italic" href={`/material/${theme.repo}/${theme.id}/${course.id}/diagram`}> + <SubTitle text="View Course Diagram" /> + </Link> + <CourseGrid course={course} theme={theme} /> <Content markdown={course.markdown} theme={theme} course={course} /> </Layout> ) diff --git a/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx b/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx new file mode 100644 index 00000000..15ebd9b0 --- /dev/null +++ b/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx @@ -0,0 +1,85 @@ +import type { NextPage, GetStaticProps, GetStaticPaths } from "next" +import prisma from "lib/prisma" +import { getMaterial, Course, Theme, Material, removeMarkdown } from "lib/material" +import Layout from "components/Layout" +import { makeSerializable } from "lib/utils" +import NavDiagram from "components/navdiagram/NavDiagram" +import Title from "components/ui/Title" +import { Event } from "lib/types" +import { PageTemplate, pageTemplate } from "lib/pageTemplate" +import revalidateTimeout from "lib/revalidateTimeout" + + +type CourseComponentProps = { + theme: Theme + course: Course + material: Material + events: Event[] + pageInfo?: PageTemplate +} + +const CourseComponent: NextPage<CourseComponentProps> = ({ + theme, + course, + material, + events, + pageInfo, +}: CourseComponentProps) => { + return ( + <Layout theme={theme} course={course} material={material} pageInfo={pageInfo}> + <Title text={course.name} /> + <NavDiagram material={material} theme={theme} course={course} /> + </Layout> + ) +} + +export const getStaticPaths: GetStaticPaths = async () => { + const material = await getMaterial() + let paths = [] + for (const theme of material.themes) { + for (const course of theme.courses) { + paths.push({ + params: { repoId: `${theme.repo}`, themeId: `${theme.id}`, courseId: `${course.id}` }, + }) + } + } + return { + paths, + fallback: false, + } +} + +export const getStaticProps: GetStaticProps = async (context) => { + const pageInfo = pageTemplate + const events = await prisma.event + .findMany({ + where: { hidden: false }, + }) + .catch((e) => { + return [] + }) + const themeId = context?.params?.themeId + if (!themeId || Array.isArray(themeId)) { + return { notFound: true } + } + const courseId = context?.params?.courseId + if (!courseId || Array.isArray(courseId)) { + return { notFound: true } + } + const material = await getMaterial() + const theme = material.themes.find((t) => t.id === themeId) + if (!theme) { + return { notFound: true } + } + const course = theme.courses.find((c) => c.id === courseId) + if (!course) { + return { notFound: true } + } + removeMarkdown(material, course) + return { + props: makeSerializable({ theme, course, material, events, pageInfo }), + revalidate: revalidateTimeout, + } +} + +export default CourseComponent From bdc4f94e86730ced7df188a0b1a8822d6335795c Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Mon, 3 Jun 2024 15:07:50 +0100 Subject: [PATCH 16/44] refactor: Update Layout component to use MuiTheme for theming This commit refactors the Layout component to use the MuiTheme from the @mui/material library for theming. It adds the necessary imports for the useTheme, ThemeProvider, and CssBaseline components. It also introduces the LightTheme and DarkTheme objects in the MuiTheme file, which define the color palette and styling for the light and dark themes respectively. --- components/Layout.tsx | 98 ++++++++++++++++++++++------------------- components/MuiTheme.tsx | 57 ++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 45 deletions(-) create mode 100644 components/MuiTheme.tsx diff --git a/components/Layout.tsx b/components/Layout.tsx index 554b69e5..51ac05ec 100644 --- a/components/Layout.tsx +++ b/components/Layout.tsx @@ -17,6 +17,9 @@ import { PageTemplate } from "lib/pageTemplate" import { SectionLink } from "./ui/LinkedSection" import { findLinks } from "lib/findSectionLinks" import PlausibleProvider from "next-plausible" +import { useTheme } from "next-themes" +import { ThemeProvider, CssBaseline } from "@mui/material" +import { LightTheme, DarkTheme } from "./MuiTheme" type Props = { material: Material @@ -33,56 +36,61 @@ const Layout: React.FC<Props> = ({ material, theme, course, section, children, p const [activeEvent, setActiveEvent] = useActiveEvent() const router = useRouter() const { data: session } = useSession() - + const { systemTheme, theme: currentTheme } = useTheme() const [showAttribution, setShowAttribution] = useState(false) const [sidebarOpen, setSidebarOpen] = useSidebarOpen(true) const sectionLinks: SectionLink[] = findLinks(material, theme, course, section, activeEvent) + + const muiTheme = React.useMemo(() => (currentTheme === "light" ? LightTheme : DarkTheme), [currentTheme]) return ( <RecoilRoot> - <div className="container mx-auto"> - <Link href="#main" className="sr-only focus:not-sr-only"> - Skip to main content - </Link> - <Header theme={theme} course={course} pageInfo={pageInfo} /> - <header> - <Navbar - material={material} - theme={theme} - course={course} - section={section} - activeEvent={activeEvent} - sidebarOpen={sidebarOpen} - setSidebarOpen={setSidebarOpen} - showAttribution={showAttribution} - setShowAttribution={setShowAttribution} - repoUrl={repoUrl} - excludes={excludes} - /> - </header> - <main id="main"> - <Overlay - material={material} - course={course} - theme={theme} - activeEvent={activeEvent} - section={section} - sidebarOpen={sidebarOpen} - setSidebarOpen={setSidebarOpen} - showAttribution={showAttribution} - setShowAttribution={setShowAttribution} - sectionLinks={sectionLinks} - /> - <PlausibleProvider - domain={process.env.NEXT_PUBLIC_PLAUSIBLE_DOMAIN ?? ""} - enabled={true} - trackLocalhost={true} - trackOutboundLinks={true} - > - <div data-testid="plausible-provider">{children}</div> - </PlausibleProvider> - </main> - <Footer pageInfo={pageInfo} /> - </div> + <ThemeProvider theme={muiTheme}> + <CssBaseline /> + <div className="container mx-auto"> + <Link href="#main" className="sr-only focus:not-sr-only"> + Skip to main content + </Link> + <Header theme={theme} course={course} pageInfo={pageInfo} /> + <header> + <Navbar + material={material} + theme={theme} + course={course} + section={section} + activeEvent={activeEvent} + sidebarOpen={sidebarOpen} + setSidebarOpen={setSidebarOpen} + showAttribution={showAttribution} + setShowAttribution={setShowAttribution} + repoUrl={repoUrl} + excludes={excludes} + /> + </header> + <main id="main"> + <Overlay + material={material} + course={course} + theme={theme} + activeEvent={activeEvent} + section={section} + sidebarOpen={sidebarOpen} + setSidebarOpen={setSidebarOpen} + showAttribution={showAttribution} + setShowAttribution={setShowAttribution} + sectionLinks={sectionLinks} + /> + <PlausibleProvider + domain={process.env.NEXT_PUBLIC_PLAUSIBLE_DOMAIN ?? ""} + enabled={true} + trackLocalhost={true} + trackOutboundLinks={true} + > + <div data-testid="plausible-provider">{children}</div> + </PlausibleProvider> + </main> + <Footer pageInfo={pageInfo} /> + </div> + </ThemeProvider> </RecoilRoot> ) } diff --git a/components/MuiTheme.tsx b/components/MuiTheme.tsx new file mode 100644 index 00000000..ec220ab7 --- /dev/null +++ b/components/MuiTheme.tsx @@ -0,0 +1,57 @@ +import { createTheme } from "@mui/material" + +export const LightTheme = createTheme({ + palette: { + mode: "light", + primary: { + main: "#000", // Primary text color + }, + background: { + default: "#fff", // Base canvas + paper: "#f8fafc", // Slightly off-white like bg-slate-50 + }, + text: { + primary: "#000", // Black text + secondary: "#374151", // Dark gray for secondary text + }, + }, + components: { + MuiPaper: { + styleOverrides: { + root: { + backgroundColor: "#f8fafc", // Similar to bg-slate-50 + borderColor: "#e5e7eb", // border-gray-200 + borderRadius: "8px", // rounded-lg + }, + }, + }, + }, +}) + +export const DarkTheme = createTheme({ + palette: { + mode: "dark", + primary: { + main: "#fff", // Primary text color in dark mode + }, + background: { + default: "#1f2937", // dark:bg-slate-800 + paper: "#374151", // dark bg-slate-800 + }, + text: { + primary: "#fff", // White text in dark mode + secondary: "#e5e7eb", // Lighter gray for secondary text + }, + }, + components: { + MuiPaper: { + styleOverrides: { + root: { + backgroundColor: "#374151", // Similar to dark:bg-slate-800 + borderColor: "#4b5563", // dark:border-gray-700 + borderRadius: "8px", // rounded-lg + }, + }, + }, + }, +}) From c7a746b29d66f03cc43c41e332288fff4aa7791c Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Mon, 3 Jun 2024 15:08:56 +0100 Subject: [PATCH 17/44] feat: Add NavDiagram component and update Material pages adds`NavDiagram` component to the to see the full repo layout via a link from /material --- components/navdiagram/NavDiagram.tsx | 13 +++++++-- pages/material/diagram.tsx | 43 ++++++++++++++++++++++++++++ pages/material/index.tsx | 8 +++++- 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 pages/material/diagram.tsx diff --git a/components/navdiagram/NavDiagram.tsx b/components/navdiagram/NavDiagram.tsx index 15c4bcc3..d0079bbb 100644 --- a/components/navdiagram/NavDiagram.tsx +++ b/components/navdiagram/NavDiagram.tsx @@ -60,8 +60,6 @@ const layoutOptionsTheme = { "elk.zoomToFit": "true", } -const padding = "[top=50.0,left=12.0,bottom=12.0,right=12.0]" - const labels = [{ width: 200, height: 70 }] const labelsTheme = [{ width: 200, height: 90 }] @@ -217,7 +215,6 @@ function generate_theme_nodes_elk(theme: Theme, includeExternalDeps: boolean = f .flat() nodes = nodes.concat(nodeDeps) } - if (nodes.length == 0) { return undefined } @@ -330,6 +327,15 @@ function generate_material_nodes(material: Material, graph: ElkNode, excludes: E height: graph.children?.[i].height, }, })) + nodes = nodes.concat( + ...material.themes.map((theme, i) => { + if (graph.children?.[i]) { + return generate_theme_nodes(material, theme, graph.children?.[i], false, excludes ? excludes : blankExcludes) + } else { + return [] + } + }) + ) return nodes } @@ -347,6 +353,7 @@ function generate_material_nodes_elk( children: generate_theme_nodes_elk(theme, false, excludes ? excludes : blankExcludes), edges: generate_theme_edges_elk(theme, excludes ? excludes : blankExcludes), })) + console.log(nodes) return nodes } diff --git a/pages/material/diagram.tsx b/pages/material/diagram.tsx new file mode 100644 index 00000000..6d019c6c --- /dev/null +++ b/pages/material/diagram.tsx @@ -0,0 +1,43 @@ +import type { NextPage, GetStaticProps } from "next" +import prisma from "lib/prisma" +import Layout from "components/Layout" +import { makeSerializable } from "lib/utils" +import { Material, getMaterial, removeMarkdown } from "lib/material" +import Content from "components/content/Content" +import NavDiagram from "components/navdiagram/NavDiagram" +import { EventFull as Event } from "lib/types" + +type HomeProps = { + material: Material + events: Event[] +} + +const Home: NextPage<HomeProps> = ({ material, events }) => { + return ( + <Layout material={material}> + <Content markdown={material.markdown} /> + <NavDiagram material={material} /> + </Layout> + ) +} + +export const getStaticProps: GetStaticProps = async (context) => { + const events = await prisma.event + .findMany({ + where: { hidden: false }, + }) + .catch((e) => { + return [] + }) + let material = await getMaterial() + removeMarkdown(material, material) + + return { + props: { + material: makeSerializable(material), + events: makeSerializable(events), + }, + } +} + +export default Home diff --git a/pages/material/index.tsx b/pages/material/index.tsx index 8e89f396..098d246d 100644 --- a/pages/material/index.tsx +++ b/pages/material/index.tsx @@ -7,6 +7,9 @@ import { EventFull as Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" import ThemeCards from "components/ThemeCards" import revalidateTimeout from "lib/revalidateTimeout" +import Title from "components/ui/Title" +import SubTitle from "components/ui/SubTitle" +import Link from "next/link" type HomeProps = { material: Material @@ -17,7 +20,10 @@ type HomeProps = { const Home: NextPage<HomeProps> = ({ material, events, pageInfo }) => { return ( <Layout material={material} pageInfo={pageInfo}> - <h1 className="text-3xl font-bold text-center p-3">Material Themes</h1> + <Title text="Material Themes" className="text-3xl font-bold text-center p-3" style={{ marginBottom: "0px" }} /> + <Link className="text-blue-500 italic" href={`/material/diagram`}> + <SubTitle text="view full diagram" /> + </Link> <ThemeCards material={material} /> </Layout> ) From 93311eac8794d5882d0d499e195018ffac85a326 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Mon, 3 Jun 2024 15:09:13 +0100 Subject: [PATCH 18/44] Add files property to Course type --- lib/material.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/material.ts b/lib/material.ts index 980115b0..315b303b 100644 --- a/lib/material.ts +++ b/lib/material.ts @@ -44,6 +44,7 @@ export type Course = { type: string attribution: Attribution[] summary: string + files: string[][] } export type Theme = { @@ -237,7 +238,6 @@ export async function getCourse(repo: string, theme: string, course: string, no_ } else { files = files as string[][] } - console.log(files.flatMap((x) => x)) // @ts-expect-error const attribution = (courseObject.attributes.attribution as Attribution[]) || [] const id = course @@ -246,7 +246,7 @@ export async function getCourse(repo: string, theme: string, course: string, no_ sections = sections.filter((section) => !excludeSections.includes(section.id)) const type = "Course" - return { id, theme, name, sections, dependsOn, markdown, type, attribution, summary } + return { id, theme, name, sections, dependsOn, markdown, type, attribution, summary, files } } // https://stackoverflow.com/questions/21792367/replace-underscores-with-spaces-and-capitalize-words From 9968353ec9dd11a4db1d3afbf6ebdee5cc81b048 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Fri, 14 Jun 2024 16:42:27 +0100 Subject: [PATCH 19/44] grids for courses --- components/navdiagram/CourseGrid.tsx | 47 +++++++++++++++++-- components/navdiagram/ThemeGrid.tsx | 29 ++++++++++++ pages/material/[repoId]/[themeId].tsx | 10 +++- pages/material/[repoId]/[themeId]/diagram.tsx | 42 +++++++++++++++++ 4 files changed, 122 insertions(+), 6 deletions(-) create mode 100644 components/navdiagram/ThemeGrid.tsx create mode 100644 pages/material/[repoId]/[themeId]/diagram.tsx diff --git a/components/navdiagram/CourseGrid.tsx b/components/navdiagram/CourseGrid.tsx index 5ee76c03..7659c39a 100644 --- a/components/navdiagram/CourseGrid.tsx +++ b/components/navdiagram/CourseGrid.tsx @@ -1,6 +1,6 @@ import React from "react" import Link from "next/link" -import { Grid, Paper, Typography, Box } from "@mui/material" +import { Grid, Paper, Typography, Box, Chip } from "@mui/material" import { Course, Theme } from "lib/material" import { useTheme } from "next-themes" @@ -22,14 +22,25 @@ function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { const commonTags = tagsArray.reduce((a, b) => a.filter((c) => b.includes(c))) return commonTags.length > 0 ? commonTags[0] : null // returns the first common tag if any } + const chipColors = ["#FF5733", "#C70039", "#900C3F", "#581845", "#1C2833", "#17202A"] + let tagColorIndex = 0 + const tagColorMap: { [key: string]: string } = {} return ( <div className="mx-auto max-w-6xl prose-slate dark:prose-invert"> - <Grid container spacing={2} sx={{ paddingBottom: "16px" }}> + <Grid container spacing={2} sx={{ paddingBottom: "16px", justifyContent: "center" }}> {files.map((column, colIndex) => { const commonTag = findCommonTag(column) return ( - <Grid item xs={12 / files.length} key={colIndex}> + <Grid + item + xs={12} + sm={8} + md={6} + lg={6} + key={colIndex} + sx={{ maxWidth: { xs: "100%", sm: "50%", md: "50%" }, flexBasis: "auto" }} + > {commonTag && ( <Box className="bg-slate-50 border-gray-200 text-black dark:bg-gray-800 dark:border-gray-700 dark:text-white p-2" @@ -48,7 +59,35 @@ function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { <Grid item xs={12} key={rowIndex}> <Link href={url}> <Paper elevation={3} sx={{ borderRadius: "0px", p: 2, textAlign: "center" }}> - <Typography variant="body1">{section ? section.name : "Unnamed Section"}</Typography> + <Box + sx={{ + width: "100%", + display: "flex", + justifyContent: "space-between", + alignItems: "center", + }} + > + <Typography variant="body1" sx={{ flex: "1", textAlign: "left" }}> + {section.name} + </Typography> + <Box sx={{ display: "flex", gap: 0.5 }}> + {section.tags.map((tag) => { + // If the tag doesn't have a color yet, assign it one + if (!tagColorMap[tag]) { + tagColorMap[tag] = chipColors[tagColorIndex % chipColors.length] + tagColorIndex++ + } + return ( + <Chip + key={tag} + label={tag} + size="small" + sx={{ backgroundColor: tagColorMap[tag], fontSize: "0.75rem", height: "20px" }} + /> + ) + })} + </Box> + </Box> </Paper> </Link> </Grid> diff --git a/components/navdiagram/ThemeGrid.tsx b/components/navdiagram/ThemeGrid.tsx new file mode 100644 index 00000000..9c203a91 --- /dev/null +++ b/components/navdiagram/ThemeGrid.tsx @@ -0,0 +1,29 @@ +import React from "react" +import Link from "next/link" +import { Grid, Paper, Typography, Box } from "@mui/material" +import { Theme } from "lib/material" + +function ThemeGrid({ theme }: { theme: Theme }) { + const repo = theme.repo + const courses = theme.courses + + return ( + <div className="mx-auto max-w-6xl prose-slate dark:prose-invert"> + <Grid container spacing={2} sx={{ paddingBottom: "16px" }}> + {courses.map((course, colIndex) => { + return ( + <Grid item xs={12 / courses.length} key={colIndex}> + <Link href={`/material/${repo}/${theme.id}/${course.id}`}> + <Paper elevation={3} sx={{ borderRadius: "0px", p: 2, textAlign: "center" }}> + <Typography variant="body1">{course ? course.name : "Unnamed Section"}</Typography> + </Paper> + </Link> + </Grid> + ) + })} + </Grid> + </div> + ) +} + +export default ThemeGrid diff --git a/pages/material/[repoId]/[themeId].tsx b/pages/material/[repoId]/[themeId].tsx index 88e4bb6c..6c556c36 100644 --- a/pages/material/[repoId]/[themeId].tsx +++ b/pages/material/[repoId]/[themeId].tsx @@ -6,9 +6,12 @@ import { makeSerializable } from "lib/utils" import Content from "components/content/Content" import NavDiagram from "components/navdiagram/NavDiagram" import Title from "components/ui/Title" +import SubTitle from "components/ui/SubTitle" import { Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" import revalidateTimeout from "lib/revalidateTimeout" +import Link from "next/link" +import ThemeGrid from "components/navdiagram/ThemeGrid" type ThemeComponentProps = { theme: Theme @@ -21,8 +24,11 @@ type ThemeComponentProps = { const ThemeComponent: NextPage<ThemeComponentProps> = ({ theme, material, events, pageInfo, excludes }) => { return ( <Layout material={material} theme={theme} pageInfo={pageInfo}> - <Title text={theme.name} /> - <NavDiagram material={material} theme={theme} excludes={excludes} /> + <Title text={theme.name} style={{ marginBottom: "0px" }} /> + <Link className="text-blue-500 italic" href={`/material/${theme.repo}/${theme.id}/diagram`}> + <SubTitle text="View Theme Diagram" /> + </Link> + <ThemeGrid theme={theme} /> <Content markdown={theme.markdown} theme={theme} /> </Layout> ) diff --git a/pages/material/[repoId]/[themeId]/diagram.tsx b/pages/material/[repoId]/[themeId]/diagram.tsx new file mode 100644 index 00000000..4fde8473 --- /dev/null +++ b/pages/material/[repoId]/[themeId]/diagram.tsx @@ -0,0 +1,42 @@ +import type { NextPage, GetStaticProps } from "next" +import prisma from "lib/prisma" +import Layout from "components/Layout" +import { makeSerializable } from "lib/utils" +import { Material, Theme, getMaterial, removeMarkdown } from "lib/material" +import Content from "components/content/Content" +import NavDiagram from "components/navdiagram/NavDiagram" + +type HomeProps = { + material: Material + theme: Theme +} + +const Home: NextPage<HomeProps> = ({ material, theme }) => { + return ( + <Layout material={material}> + <Content markdown={material.markdown} theme={theme} /> + <NavDiagram material={material} /> + </Layout> + ) +} + +export const getStaticProps: GetStaticProps = async (context) => { + const events = await prisma.event + .findMany({ + where: { hidden: false }, + }) + .catch((e) => { + return [] + }) + let material = await getMaterial() + removeMarkdown(material, material) + + return { + props: { + material: makeSerializable(material), + events: makeSerializable(events), + }, + } +} + +export default Home From 018af6ce49ba24987373f20f25b376cae895759e Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Thu, 11 Jul 2024 15:52:16 +0100 Subject: [PATCH 20/44] fixed rounding on coursegrid --- components/MuiTheme.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/MuiTheme.tsx b/components/MuiTheme.tsx index ec220ab7..adffc360 100644 --- a/components/MuiTheme.tsx +++ b/components/MuiTheme.tsx @@ -21,7 +21,7 @@ export const LightTheme = createTheme({ root: { backgroundColor: "#f8fafc", // Similar to bg-slate-50 borderColor: "#e5e7eb", // border-gray-200 - borderRadius: "8px", // rounded-lg + borderRadius: "8", // rounded-lg }, }, }, From 79c2998106a3f95450a368979a1e556a00203a72 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Thu, 11 Jul 2024 15:52:43 +0100 Subject: [PATCH 21/44] fixed rounding on coursegrid --- components/navdiagram/CourseGrid.tsx | 18 ++++++++++++++---- components/navdiagram/NavDiagram.tsx | 1 - components/navdiagram/ThemeGrid.tsx | 14 ++++++++++---- scripts/table.ts | 1 - 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/components/navdiagram/CourseGrid.tsx b/components/navdiagram/CourseGrid.tsx index 7659c39a..3f05645b 100644 --- a/components/navdiagram/CourseGrid.tsx +++ b/components/navdiagram/CourseGrid.tsx @@ -2,7 +2,6 @@ import React from "react" import Link from "next/link" import { Grid, Paper, Typography, Box, Chip } from "@mui/material" import { Course, Theme } from "lib/material" -import { useTheme } from "next-themes" function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { const files = course.files @@ -44,7 +43,7 @@ function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { {commonTag && ( <Box className="bg-slate-50 border-gray-200 text-black dark:bg-gray-800 dark:border-gray-700 dark:text-white p-2" - sx={{ borderRadius: "0px", textAlign: "center" }} + sx={{ borderRadius: "8px 8px 0 0", textAlign: "center" }} > <Typography variant="h6">{commonTag.toUpperCase()}</Typography> </Box> @@ -54,11 +53,22 @@ function CourseGrid({ course, theme }: { course: Course; theme: Theme }) { const section = findSectionByName(file) if (!section) return null const url = `/material/${repo}/${course.theme}/${course.id}/${section.id}` - console.log(url) + + // Determine if this is the first or last item + const isFirstItem = rowIndex === 0 && !commonTag + const isLastItem = rowIndex === column.length - 1 + return ( <Grid item xs={12} key={rowIndex}> <Link href={url}> - <Paper elevation={3} sx={{ borderRadius: "0px", p: 2, textAlign: "center" }}> + <Paper + elevation={3} + sx={{ + borderRadius: isFirstItem ? "8px 8px 0 0" : isLastItem ? "0 0 8px 8px" : "0px", + p: 2, + textAlign: "center", + }} + > <Box sx={{ width: "100%", diff --git a/components/navdiagram/NavDiagram.tsx b/components/navdiagram/NavDiagram.tsx index d0079bbb..6e8285be 100644 --- a/components/navdiagram/NavDiagram.tsx +++ b/components/navdiagram/NavDiagram.tsx @@ -353,7 +353,6 @@ function generate_material_nodes_elk( children: generate_theme_nodes_elk(theme, false, excludes ? excludes : blankExcludes), edges: generate_theme_edges_elk(theme, excludes ? excludes : blankExcludes), })) - console.log(nodes) return nodes } diff --git a/components/navdiagram/ThemeGrid.tsx b/components/navdiagram/ThemeGrid.tsx index 9c203a91..64119044 100644 --- a/components/navdiagram/ThemeGrid.tsx +++ b/components/navdiagram/ThemeGrid.tsx @@ -1,6 +1,6 @@ import React from "react" import Link from "next/link" -import { Grid, Paper, Typography, Box } from "@mui/material" +import { Grid, Paper, Typography, Box, Divider } from "@mui/material" import { Theme } from "lib/material" function ThemeGrid({ theme }: { theme: Theme }) { @@ -12,10 +12,16 @@ function ThemeGrid({ theme }: { theme: Theme }) { <Grid container spacing={2} sx={{ paddingBottom: "16px" }}> {courses.map((course, colIndex) => { return ( - <Grid item xs={12 / courses.length} key={colIndex}> + <Grid item xs={Math.max(12 / courses.length, 4)} key={colIndex}> <Link href={`/material/${repo}/${theme.id}/${course.id}`}> - <Paper elevation={3} sx={{ borderRadius: "0px", p: 2, textAlign: "center" }}> - <Typography variant="body1">{course ? course.name : "Unnamed Section"}</Typography> + <Paper elevation={3} sx={{ p: 2, textAlign: "center" }}> + <Typography variant="h5" component="h2"> + {course ? course.name : "Unnamed Section"} + </Typography> + <Divider sx={{ my: 1, width: "90%", mx: "auto" }} /> + <Typography variant="body1" sx={{ mt: 1, textAlign: "left" }}> + {course.summary} + </Typography> </Paper> </Link> </Grid> diff --git a/scripts/table.ts b/scripts/table.ts index 114a4622..7b39f11c 100644 --- a/scripts/table.ts +++ b/scripts/table.ts @@ -8,7 +8,6 @@ async function generateTable() { const hostname = "https://train.oxrse.uk" let content = `| ${headers.join(" | ")} |\n| ${headers.map(() => "---").join(" | ")} |\n` for (let theme of material.themes) { - console.log(theme.name) for (let course of theme.courses) { const courseString = `${theme.id}.${course.id}` const themeString = `${theme.id}` From eecc32133a80ec576c7007eef2d35afcc1cf6169 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Thu, 11 Jul 2024 22:24:36 +0100 Subject: [PATCH 22/44] refactor: Add getStaticPaths function to diagram.tsx This commit adds the getStaticPaths function to the diagram.tsx file in the pages/material/[repoId]/[themeId] directory. The function generates the paths for the dynamic routes based on the material data retrieved from the getMaterial function. Each path corresponds to a specific combination of repoId, themeId, and courseId. This change ensures that the dynamic routes are properly generated and accessible for the material pages. --- cypress/component/EventCommentThreads.cy.tsx | 1 + pages/material/[repoId]/[themeId]/diagram.tsx | 18 +++++++++++++++++- pages/material/diagram.tsx | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/cypress/component/EventCommentThreads.cy.tsx b/cypress/component/EventCommentThreads.cy.tsx index acde7875..f028114f 100644 --- a/cypress/component/EventCommentThreads.cy.tsx +++ b/cypress/component/EventCommentThreads.cy.tsx @@ -32,6 +32,7 @@ describe("EventCommentThreads component", () => { type: "theme", courses: [ { + files: [], id: "course1", name: "Course 1", summary: "", diff --git a/pages/material/[repoId]/[themeId]/diagram.tsx b/pages/material/[repoId]/[themeId]/diagram.tsx index 4fde8473..ab30cdd4 100644 --- a/pages/material/[repoId]/[themeId]/diagram.tsx +++ b/pages/material/[repoId]/[themeId]/diagram.tsx @@ -1,4 +1,4 @@ -import type { NextPage, GetStaticProps } from "next" +import type { NextPage, GetStaticProps, GetStaticPaths } from "next" import prisma from "lib/prisma" import Layout from "components/Layout" import { makeSerializable } from "lib/utils" @@ -39,4 +39,20 @@ export const getStaticProps: GetStaticProps = async (context) => { } } +export const getStaticPaths: GetStaticPaths = async () => { + const material = await getMaterial() + let paths = [] + for (const theme of material.themes) { + for (const course of theme.courses) { + paths.push({ + params: { repoId: `${theme.repo}`, themeId: `${theme.id}`, courseId: `${course.id}` }, + }) + } + } + return { + paths, + fallback: false, + } +} + export default Home diff --git a/pages/material/diagram.tsx b/pages/material/diagram.tsx index 6d019c6c..227287f5 100644 --- a/pages/material/diagram.tsx +++ b/pages/material/diagram.tsx @@ -1,4 +1,4 @@ -import type { NextPage, GetStaticProps } from "next" +import type { NextPage, GetStaticProps, GetStaticPaths } from "next" import prisma from "lib/prisma" import Layout from "components/Layout" import { makeSerializable } from "lib/utils" From 9e09d067af807b2a163b4ccca7638760bc364450 Mon Sep 17 00:00:00 2001 From: Alasdair Wilson <alasdair.wlsn@googlemail.com> Date: Thu, 11 Jul 2024 22:27:53 +0100 Subject: [PATCH 23/44] prettier --- pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx b/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx index 15ebd9b0..ac48cd7b 100644 --- a/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx +++ b/pages/material/[repoId]/[themeId]/[courseId]/diagram.tsx @@ -9,7 +9,6 @@ import { Event } from "lib/types" import { PageTemplate, pageTemplate } from "lib/pageTemplate" import revalidateTimeout from "lib/revalidateTimeout" - type CourseComponentProps = { theme: Theme course: Course From 5ea0f675a461ce2f742805429e2a196c79485cbc Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Fri, 12 Jul 2024 15:01:36 +0100 Subject: [PATCH 24/44] copy heading button works with window href --- components/content/Paragraph.tsx | 72 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 1c20e187..a5261f66 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -174,41 +174,45 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </> ) : ( <> - <Tag id={content?.toString().replaceAll(" ", "-")}> - {content}{" "} - <CopyToClipboard text={content?.toString() ?? ""}> - <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> - <FaClipboard className="group-hover:text-white" /> - <span className="group-hover:text-white">Copy</span> - </button> - </CopyToClipboard> - </Tag> - {activeEvent && ( - <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> - <div className={`w-[420px]`}> - {similarThreads?.map((thread) => ( - <Thread - key={thread.id} - thread={thread.id} - active={activeThreadId === thread.id} - setActive={(active: boolean) => (active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined))} - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(thread)} - /> - ))} - {tempThread && ( - <Thread - key={tempThread.id} - thread={tempThread} - active={tempActive} - setActive={setTempActive} - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(tempThread)} - /> - )} + <div data-cy="paragraph" ref={ref} className="relative pb-2"> + <Tag id={content?.toString().replaceAll(" ", "-")}> + {content}{" "} + <CopyToClipboard text={(typeof window !== 'undefined' ? window.location.href : '') + "#" + content?.toString().replaceAll(" ", "-") ?? ""}> + <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <FaClipboard className="group-hover:text-white" /> + <span className="group-hover:text-white">Copy</span> + </button> + </CopyToClipboard> + </Tag> + {activeEvent && ( + <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> + <div className={`w-[420px]`}> + {similarThreads?.map((thread) => ( + <Thread + key={thread.id} + thread={thread.id} + active={activeThreadId === thread.id} + setActive={(active: boolean) => + active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) + } + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + <Thread + key={tempThread.id} + thread={tempThread} + active={tempActive} + setActive={setTempActive} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(tempThread)} + /> + )} + </div> </div> - </div> - )} + )} + </div> {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> ) From 73ad4699d4351ed143ec045f19f544be1ba59c78 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Fri, 12 Jul 2024 15:04:47 +0100 Subject: [PATCH 25/44] prettier --- components/content/Paragraph.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index a5261f66..f0d192b5 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -177,7 +177,13 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => <div data-cy="paragraph" ref={ref} className="relative pb-2"> <Tag id={content?.toString().replaceAll(" ", "-")}> {content}{" "} - <CopyToClipboard text={(typeof window !== 'undefined' ? window.location.href : '') + "#" + content?.toString().replaceAll(" ", "-") ?? ""}> + <CopyToClipboard + text={ + (typeof window !== "undefined" ? window.location.href : "") + + "#" + + content?.toString().replaceAll(" ", "-") ?? "" + } + > <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Copy</span> From dec2cdd31222d77619cf1060148019877bd106d4 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Tue, 9 Jul 2024 12:32:30 +0100 Subject: [PATCH 26/44] create custom heading components for react-markdown --- components/content/Content.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/components/content/Content.tsx b/components/content/Content.tsx index 22db640b..a5b66e43 100644 --- a/components/content/Content.tsx +++ b/components/content/Content.tsx @@ -20,7 +20,7 @@ import Solution from "./Solution" import { first } from "cypress/types/lodash" import remarkDirective from "remark-directive" import remarkDirectiveRehype from "remark-directive-rehype" -import { CodeComponent, CodeProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" +import { CodeComponent, CodeProps, HeadingProps, ReactMarkdownProps } from "react-markdown/lib/ast-to-react" import Callout from "../Callout" import { Course, Section, Theme } from "lib/material" import Paragraph from "./Paragraph" @@ -56,6 +56,13 @@ const list = (sectionStr: string) => { return list } +const heading = (sectionStr: string, tag: string) => { + function heading({ node, children, ...props }: HeadingProps) { + return <Paragraph content={children} section={sectionStr} /> + } + return heading +} + let solutionCount = 0 function solution({ node, children, ...props }: ReactMarkdownProps) { solutionCount++ @@ -161,6 +168,8 @@ const Content: React.FC<Props> = ({ markdown, theme, course, section }) => { code, p: p(sectionStr), li: list(sectionStr), + h2: heading(sectionStr, "h2"), + h3: heading(sectionStr, "h3"), }} > {markdown} From 8050b7bf1c3fb5e91125ae73000a9a95ee244705 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Tue, 9 Jul 2024 12:35:31 +0100 Subject: [PATCH 27/44] return variable <Tag> instead of <p> --- components/content/Paragraph.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index e64d2343..1ccec08a 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -20,9 +20,10 @@ const as = nlp.as interface ParagraphProps { content: React.ReactNode section: string + tag: string } -const Paragraph: React.FC<ParagraphProps> = ({ content, section }) => { +const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => { const ref = useRef<HTMLDivElement>(null) const [activeEvent, setActiveEvent] = useActiveEvent() const { commentThreads, error, isLoading, mutate } = useCommentThreads(activeEvent?.id) @@ -30,6 +31,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section }) => { const [tempThread, setTempThread] = useState<CommentThread | undefined>(undefined) const [tempActive, setTempActive] = useState<boolean>(false) const email = useSession().data?.user?.email + const Tag = tag as keyof JSX.IntrinsicElements const { similarThreads, contentText } = useMemo(() => { let contentText = "" @@ -136,7 +138,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section }) => { return ( <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> - <p className="m-0 pb-0">{content}</p> + <Tag id={Tag !== 'p' ? content?.toString().replace(' ', '-').toLowerCase() : ''} className="m-0 pb-0">{content}</Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> From d63e4680213fa5aaf639e0b9a091459292824543 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Tue, 9 Jul 2024 12:37:01 +0100 Subject: [PATCH 28/44] add tag parameter to p and list react-markdown components --- components/content/Content.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/components/content/Content.tsx b/components/content/Content.tsx index a5b66e43..970a4570 100644 --- a/components/content/Content.tsx +++ b/components/content/Content.tsx @@ -40,7 +40,7 @@ function reactMarkdownRemarkDirective() { const p = (sectionStr: string) => { function p({ node, children, ...props }: ReactMarkdownProps) { - return <Paragraph content={children} section={sectionStr} /> + return <Paragraph content={children} section={sectionStr} tag="p" /> } return p } @@ -49,7 +49,7 @@ const list = (sectionStr: string) => { function list({ node, children, ...props }: ReactMarkdownProps) { return ( <li className="mdli"> - <Paragraph content={children} section={sectionStr} /> + <Paragraph content={children} section={sectionStr} tag="p" /> </li> ) } @@ -58,7 +58,7 @@ const list = (sectionStr: string) => { const heading = (sectionStr: string, tag: string) => { function heading({ node, children, ...props }: HeadingProps) { - return <Paragraph content={children} section={sectionStr} /> + return <Paragraph content={children} section={sectionStr} tag={tag} /> } return heading } From 359b440cbeb325dafb1fb930f8aacbc3aee52220 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Tue, 9 Jul 2024 12:41:14 +0100 Subject: [PATCH 29/44] replaceAll not replace --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 1ccec08a..344a06ed 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -138,7 +138,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => return ( <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> - <Tag id={Tag !== 'p' ? content?.toString().replace(' ', '-').toLowerCase() : ''} className="m-0 pb-0">{content}</Tag> + <Tag id={Tag !== 'p' ? content?.toString().replaceAll(' ', '-').toLowerCase() : ''} className="m-0 pb-0">{content}</Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> From 7ba02fefd6d6468f15116b738fb741393e3d8947 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Tue, 9 Jul 2024 14:57:29 +0100 Subject: [PATCH 30/44] style headings differently --- components/content/Paragraph.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 344a06ed..d337b38b 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -137,8 +137,13 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => return ( <> - <div data-cy="paragraph" ref={ref} className="relative pb-2"> - <Tag id={Tag !== 'p' ? content?.toString().replaceAll(' ', '-').toLowerCase() : ''} className="m-0 pb-0">{content}</Tag> + <div data-cy="paragraph" ref={ref} className="relative pb-0"> + <Tag + id={Tag !== "p" ? content?.toString().replaceAll(" ", "-").toLowerCase() : ""} + className={Tag === "p" ? "m-0" : "mb-6"} + > + {content} + </Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> From 547ff6c8a608085b760f0a9efb47b8ce625449bd Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Wed, 10 Jul 2024 14:57:36 +0100 Subject: [PATCH 31/44] return separate <p> and <h> jsx --- components/content/Paragraph.tsx | 46 +++++++++++++++++++++++++------- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index d337b38b..f4b300ac 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -135,15 +135,10 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => } } - return ( - <> - <div data-cy="paragraph" ref={ref} className="relative pb-0"> - <Tag - id={Tag !== "p" ? content?.toString().replaceAll(" ", "-").toLowerCase() : ""} - className={Tag === "p" ? "m-0" : "mb-6"} - > - {content} - </Tag> + return tag === "p" ? ( + <> + <div data-cy="paragraph" ref={ref} className="relative pb-2"> + <p className="m-0 pb-0">{content}</p> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> @@ -175,6 +170,39 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </div> {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> + ) : ( + <> + <Tag id={content?.toString().replaceAll(' ', '-').toLowerCase()}>{content}</Tag> + {activeEvent && ( + <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> + <div className={`w-[420px]`}> + {similarThreads?.map((thread) => ( + <Thread + key={thread.id} + thread={thread.id} + active={activeThreadId === thread.id} + setActive={(active: boolean) => + active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) + } + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + <Thread + key={tempThread.id} + thread={tempThread} + active={tempActive} + setActive={setTempActive} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(tempThread)} + /> + )} + </div> + </div> + )} + {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} + </> ) } From 44f0a1e608b5c2962a771bb528ebbf9a01ebae9d Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Wed, 10 Jul 2024 15:03:14 +0100 Subject: [PATCH 32/44] upper case IDs --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index f4b300ac..3bd323ba 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -172,7 +172,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </> ) : ( <> - <Tag id={content?.toString().replaceAll(' ', '-').toLowerCase()}>{content}</Tag> + <Tag id={content?.toString().replaceAll(' ', '-')}>{content}</Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> From bfdf8df464da7fdef4bf0e67768ef4b773bd1bea Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Wed, 10 Jul 2024 15:43:56 +0100 Subject: [PATCH 33/44] prettier --- components/content/Paragraph.tsx | 58 +++++++++++++++----------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 3bd323ba..d5f54d29 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -136,7 +136,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => } return tag === "p" ? ( - <> + <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> <p className="m-0 pb-0">{content}</p> {activeEvent && ( @@ -172,36 +172,34 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </> ) : ( <> - <Tag id={content?.toString().replaceAll(' ', '-')}>{content}</Tag> - {activeEvent && ( - <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> - <div className={`w-[420px]`}> - {similarThreads?.map((thread) => ( - <Thread - key={thread.id} - thread={thread.id} - active={activeThreadId === thread.id} - setActive={(active: boolean) => - active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) - } - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(thread)} - /> - ))} - {tempThread && ( - <Thread - key={tempThread.id} - thread={tempThread} - active={tempActive} - setActive={setTempActive} - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(tempThread)} - /> - )} - </div> + <Tag id={content?.toString().replaceAll(" ", "-")}>{content}</Tag> + {activeEvent && ( + <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> + <div className={`w-[420px]`}> + {similarThreads?.map((thread) => ( + <Thread + key={thread.id} + thread={thread.id} + active={activeThreadId === thread.id} + setActive={(active: boolean) => (active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined))} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + <Thread + key={tempThread.id} + thread={tempThread} + active={tempActive} + setActive={setTempActive} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(tempThread)} + /> + )} </div> - )} - {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} + </div> + )} + {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> ) } From 0080b1a9d0ae0a87ff686a2555721e4c257b82c5 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Thu, 11 Jul 2024 10:25:25 +0100 Subject: [PATCH 34/44] tag param optional, default <p> --- components/content/Paragraph.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index d5f54d29..2e57e174 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -20,7 +20,7 @@ const as = nlp.as interface ParagraphProps { content: React.ReactNode section: string - tag: string + tag?: string } const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => { From 8755d9b7de8ffd2c48e1cfb152016ae50349e590 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Thu, 11 Jul 2024 14:56:40 +0100 Subject: [PATCH 35/44] fixed comment position for headings --- components/content/Paragraph.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 2e57e174..88d46cc5 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -171,7 +171,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> ) : ( - <> + <div ref={ref} data-cy="paragraph" className="relative"> <Tag id={content?.toString().replaceAll(" ", "-")}>{content}</Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> @@ -200,7 +200,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </div> )} {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} - </> + </div> ) } From 3a471da2e8a2430b049f88c2d573422196168ec9 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Thu, 11 Jul 2024 15:20:54 +0100 Subject: [PATCH 36/44] added copy button, broken heading comment position --- components/content/Paragraph.tsx | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 88d46cc5..1c20e187 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -12,6 +12,8 @@ import useActiveEvent from "lib/hooks/useActiveEvents" import { Comment } from "pages/api/comment/[commentId]" import { CommentThread } from "pages/api/commentThread" import { useSession } from "next-auth/react" +import CopyToClipboard from "react-copy-to-clipboard" +import { FaClipboard } from "react-icons/fa" const nlp = winkNLP(model) const its = nlp.its @@ -171,8 +173,16 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> ) : ( - <div ref={ref} data-cy="paragraph" className="relative"> - <Tag id={content?.toString().replaceAll(" ", "-")}>{content}</Tag> + <> + <Tag id={content?.toString().replaceAll(" ", "-")}> + {content}{" "} + <CopyToClipboard text={content?.toString() ?? ""}> + <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <FaClipboard className="group-hover:text-white" /> + <span className="group-hover:text-white">Copy</span> + </button> + </CopyToClipboard> + </Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> <div className={`w-[420px]`}> @@ -200,7 +210,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </div> )} {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} - </div> + </> ) } From 1b654365b2c835b42425ea2e6c21f064110f2b54 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Fri, 12 Jul 2024 15:01:36 +0100 Subject: [PATCH 37/44] copy heading button works with window href --- components/content/Paragraph.tsx | 72 +++++++++++++++++--------------- 1 file changed, 38 insertions(+), 34 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 1c20e187..a5261f66 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -174,41 +174,45 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => </> ) : ( <> - <Tag id={content?.toString().replaceAll(" ", "-")}> - {content}{" "} - <CopyToClipboard text={content?.toString() ?? ""}> - <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> - <FaClipboard className="group-hover:text-white" /> - <span className="group-hover:text-white">Copy</span> - </button> - </CopyToClipboard> - </Tag> - {activeEvent && ( - <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> - <div className={`w-[420px]`}> - {similarThreads?.map((thread) => ( - <Thread - key={thread.id} - thread={thread.id} - active={activeThreadId === thread.id} - setActive={(active: boolean) => (active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined))} - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(thread)} - /> - ))} - {tempThread && ( - <Thread - key={tempThread.id} - thread={tempThread} - active={tempActive} - setActive={setTempActive} - finaliseThread={finaliseThread} - onDelete={() => handleDeleteThread(tempThread)} - /> - )} + <div data-cy="paragraph" ref={ref} className="relative pb-2"> + <Tag id={content?.toString().replaceAll(" ", "-")}> + {content}{" "} + <CopyToClipboard text={(typeof window !== 'undefined' ? window.location.href : '') + "#" + content?.toString().replaceAll(" ", "-") ?? ""}> + <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <FaClipboard className="group-hover:text-white" /> + <span className="group-hover:text-white">Copy</span> + </button> + </CopyToClipboard> + </Tag> + {activeEvent && ( + <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> + <div className={`w-[420px]`}> + {similarThreads?.map((thread) => ( + <Thread + key={thread.id} + thread={thread.id} + active={activeThreadId === thread.id} + setActive={(active: boolean) => + active ? setActiveThreadId(thread.id) : setActiveThreadId(undefined) + } + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(thread)} + /> + ))} + {tempThread && ( + <Thread + key={tempThread.id} + thread={tempThread} + active={tempActive} + setActive={setTempActive} + finaliseThread={finaliseThread} + onDelete={() => handleDeleteThread(tempThread)} + /> + )} + </div> </div> - </div> - )} + )} + </div> {activeEvent && <Popover target={ref?.current || undefined} onCreate={handleCreateThread} />} </> ) From 56f568a40fc67c8caa6e956140d87fde9de9cfed Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Fri, 12 Jul 2024 15:04:47 +0100 Subject: [PATCH 38/44] prettier --- components/content/Paragraph.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index a5261f66..f0d192b5 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -177,7 +177,13 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => <div data-cy="paragraph" ref={ref} className="relative pb-2"> <Tag id={content?.toString().replaceAll(" ", "-")}> {content}{" "} - <CopyToClipboard text={(typeof window !== 'undefined' ? window.location.href : '') + "#" + content?.toString().replaceAll(" ", "-") ?? ""}> + <CopyToClipboard + text={ + (typeof window !== "undefined" ? window.location.href : "") + + "#" + + content?.toString().replaceAll(" ", "-") ?? "" + } + > <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Copy</span> From a92c026ad30256465cb456b0bb67e4ca0d232f2e Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Fri, 12 Jul 2024 15:29:35 +0100 Subject: [PATCH 39/44] fix heading copy position --- components/content/Paragraph.tsx | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index f0d192b5..5fd546a6 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -34,6 +34,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => const [tempActive, setTempActive] = useState<boolean>(false) const email = useSession().data?.user?.email const Tag = tag as keyof JSX.IntrinsicElements + const headingContent = content?.toString().replaceAll(" ", "-") const { similarThreads, contentText } = useMemo(() => { let contentText = "" @@ -175,16 +176,12 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => ) : ( <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> - <Tag id={content?.toString().replaceAll(" ", "-")}> + <Tag id={headingContent} className="mt-4 flex justify-start gap-2"> {content}{" "} <CopyToClipboard - text={ - (typeof window !== "undefined" ? window.location.href : "") + - "#" + - content?.toString().replaceAll(" ", "-") ?? "" - } + text={(typeof window !== "undefined" ? window.location.href : "") + "#" + headingContent ?? ""} > - <button className="group absolute top-0 right-0 bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <button className="bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Copy</span> </button> From f5882cea91b556175a3b8ae5bebd1ccfd28eaead Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Mon, 15 Jul 2024 11:50:55 +0100 Subject: [PATCH 40/44] put heading content in variable --- components/content/Paragraph.tsx | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 5fd546a6..27527a52 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -138,6 +138,18 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => } } + const onCopyHandler = () => { + setIsCopied(true) + setTimeout(() => { + setIsCopied(false) + }, 2000) + } + + const generateHeadingURL = () => { + const href: string = (typeof window !== "undefined" ? window.location.href.split('#')[0] : "") + return href + "#" + headingContent ?? "" + } + return tag === "p" ? ( <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> @@ -176,16 +188,17 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => ) : ( <> <div data-cy="paragraph" ref={ref} className="relative pb-2"> - <Tag id={headingContent} className="mt-4 flex justify-start gap-2"> + <Tag id={headingContent} className="flex justify-start gap-1"> {content}{" "} <CopyToClipboard - text={(typeof window !== "undefined" ? window.location.href : "") + "#" + headingContent ?? ""} + text={generateHeadingURL()} > <button className="bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Copy</span> </button> </CopyToClipboard> + {isCopied && <span className="text-xs text-green-500">Copied!</span>} </Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> From df1d4c30805039f259f6c458acdc53c5d56daf95 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Mon, 15 Jul 2024 12:12:56 +0100 Subject: [PATCH 41/44] display share button only on hover --- components/content/Paragraph.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 27527a52..e90f8d0f 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -35,6 +35,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => const email = useSession().data?.user?.email const Tag = tag as keyof JSX.IntrinsicElements const headingContent = content?.toString().replaceAll(" ", "-") + const [isCopied, setIsCopied] = useState(false) const { similarThreads, contentText } = useMemo(() => { let contentText = "" @@ -193,9 +194,9 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => <CopyToClipboard text={generateHeadingURL()} > - <button className="bg-transparent text-xs text-grey-700 hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <button className="bg-transparent text-xs text-transparent hover:text-white hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> <FaClipboard className="group-hover:text-white" /> - <span className="group-hover:text-white">Copy</span> + <span className="group-hover:text-white">Share</span> </button> </CopyToClipboard> {isCopied && <span className="text-xs text-green-500">Copied!</span>} From 7551a38eb0fd1cd29d1e2c4aa3f0f9e191876abc Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Mon, 15 Jul 2024 12:30:14 +0100 Subject: [PATCH 42/44] fix styling changes due to turning headings into paragraphs --- styles/globals.css | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/styles/globals.css b/styles/globals.css index 3865839b..80a2d741 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -26,10 +26,16 @@ body { /* CSS to target the first h1 or h2 inside a Callout */ .callout > h1:first-child, -.callout > h2:first-child { +.callout > h2:first-child, +.callout > div > h1:first-child, +.callout > div > h2:first-child { margin-top: 16px; } +.prose > h1:first-child { + margin-top: 0px; +} + /* lists in markdown Content */ li.mdli { display: list-item; From 595cd570fe4abaf5596ebc9b0abbe2ab5feb3ff0 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Mon, 15 Jul 2024 12:38:39 +0100 Subject: [PATCH 43/44] fix styling of copy heading button and first heading of content page --- components/content/Paragraph.tsx | 6 +++--- styles/globals.css | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index e90f8d0f..6cc628ff 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -143,7 +143,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => setIsCopied(true) setTimeout(() => { setIsCopied(false) - }, 2000) + }, 1500) } const generateHeadingURL = () => { @@ -194,12 +194,12 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => <CopyToClipboard text={generateHeadingURL()} > - <button className="bg-transparent text-xs text-transparent hover:text-white hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1"> + <button className="bg-transparent text-xs text-transparent hover:text-white hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1" onClick={onCopyHandler}> <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Share</span> </button> </CopyToClipboard> - {isCopied && <span className="text-xs text-green-500">Copied!</span>} + {isCopied && <span className="text-xs text-green-500 flex items-center">Copied to clipboard!</span>} </Tag> {activeEvent && ( <div className={`absolute top-0 right-0 md:-right-6 xl:-right-[420px]`}> diff --git a/styles/globals.css b/styles/globals.css index 80a2d741..73367dd6 100644 --- a/styles/globals.css +++ b/styles/globals.css @@ -32,7 +32,7 @@ body { margin-top: 16px; } -.prose > h1:first-child { +.prose > div:first-child > h2 { margin-top: 0px; } From edc90debb22e489d47e6fef1cff74f94b7eabd53 Mon Sep 17 00:00:00 2001 From: Dan Kimberley <danielkimberley@gmail.com> Date: Mon, 15 Jul 2024 14:26:47 +0100 Subject: [PATCH 44/44] prettier --- components/content/Paragraph.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/components/content/Paragraph.tsx b/components/content/Paragraph.tsx index 6cc628ff..b03ed798 100644 --- a/components/content/Paragraph.tsx +++ b/components/content/Paragraph.tsx @@ -147,7 +147,7 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => } const generateHeadingURL = () => { - const href: string = (typeof window !== "undefined" ? window.location.href.split('#')[0] : "") + const href: string = typeof window !== "undefined" ? window.location.href.split("#")[0] : "" return href + "#" + headingContent ?? "" } @@ -191,10 +191,11 @@ const Paragraph: React.FC<ParagraphProps> = ({ content, section, tag = "p" }) => <div data-cy="paragraph" ref={ref} className="relative pb-2"> <Tag id={headingContent} className="flex justify-start gap-1"> {content}{" "} - <CopyToClipboard - text={generateHeadingURL()} - > - <button className="bg-transparent text-xs text-transparent hover:text-white hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1" onClick={onCopyHandler}> + <CopyToClipboard text={generateHeadingURL()}> + <button + className="bg-transparent text-xs text-transparent hover:text-white hover:bg-grey-900 px-2 py-1 rounded flex items-center space-x-1" + onClick={onCopyHandler} + > <FaClipboard className="group-hover:text-white" /> <span className="group-hover:text-white">Share</span> </button>