From 99acb0f4702b36817b5960a712cb046990d78e15 Mon Sep 17 00:00:00 2001 From: Aditya Thakral Date: Wed, 9 Jun 2021 04:45:25 -0400 Subject: [PATCH] Autogenerate read all section --- components/OrganizedContent.tsx | 182 ++++++++++-------- components/playground.tsx | 35 +--- .../duties-of-officers.organized-content.mdx | 2 +- .../executive-council.organized-content.mdx | 2 +- .../membership.organized-content.mdx | 2 +- .../constitution/name.organized-content.mdx | 2 +- .../officers.organized-content.mdx | 2 +- .../purpose.organized-content.mdx | 2 +- .../read-all.organized-content.mdx | 6 - next-env.d.ts | 2 +- 10 files changed, 119 insertions(+), 118 deletions(-) delete mode 100644 content/playground/constitution/read-all.organized-content.mdx diff --git a/components/OrganizedContent.tsx b/components/OrganizedContent.tsx index 6de18cdc..0efaedac 100644 --- a/components/OrganizedContent.tsx +++ b/components/OrganizedContent.tsx @@ -3,85 +3,79 @@ import styles from "./OrganizedContent.module.css"; export interface LinkProps { className?: string; - url: string; - children: string | ReactNode | (string | ReactNode)[]; + id: string; + children: ReactNode; } type Link = ComponentType; -interface Heading { +interface Section { + id: string; title: string; - url: string; - content: ReactNode; + Content: ComponentType; } +const READ_ALL_TITLE = "Read All"; +export const READ_ALL_ID = "read-all"; + interface Props { - headings: Heading[]; - currentIndex: number; - link: Link; - children: ReactNode; -} - -interface ChildProps { - headings: Heading[]; - currentIndex: number; + sections: Section[]; + currentId: string; link: Link; } -export const OrganizedContent = ({ - headings, - currentIndex, - link: Link, - children, -}: Props) => { - const isReadAll = headings[currentIndex].title === "Read All"; +export function OrganizedContent(props: Props) { + const sections = createSections(props.sections); + const currentIndex = sections.findIndex(({ id }) => id === props.currentId); - const readAllContent = headings - .filter((heading: { title: string }) => heading.title !== "Read All") - .map((heading) => ( -
-

{heading.title}

- {heading.content} -
- )); + if (currentIndex < 0) { + throw new Error(`Section with ID ${props.currentId} was not found`); + } - const childProps: ChildProps = { - headings: headings, - currentIndex: currentIndex, - link: Link, - }; + const section = sections[currentIndex]; + const isReadAll = section.id === READ_ALL_ID; return (
-
); -}; +} -const Nav = ({ headings, currentIndex, link: Link }: ChildProps) => { +interface NavProps { + sections: Section[]; + currentIndex: number; + link: Link; +} + +function Nav({ sections, currentIndex, link: Link }: NavProps) { return (
- {headings.map((heading, index) => ( + {sections.map((section, index) => (
{index === currentIndex && ( @@ -93,9 +87,9 @@ const Nav = ({ headings, currentIndex, link: Link }: ChildProps) => { " " + (index === currentIndex ? styles.navLinkSelected : "") } - url={heading.url} + id={section.id} > - {heading.title} + {section.title}
@@ -103,62 +97,90 @@ const Nav = ({ headings, currentIndex, link: Link }: ChildProps) => { ))}
); -}; +} -const Footer = ({ headings, currentIndex, link: Link }: ChildProps) => { - const prevHeading = - currentIndex > 0 && headings[currentIndex - 1].title !== "Read All" - ? headings[currentIndex - 1] +interface FooterProps { + sections: Section[]; + currentIndex: number; + link: Link; +} + +function Footer({ sections, currentIndex, link: Link }: FooterProps) { + const prevSection = + currentIndex > 0 && sections[currentIndex - 1].id !== READ_ALL_ID + ? sections[currentIndex - 1] : undefined; - const nextHeading = - currentIndex < headings.length - 1 && - headings[currentIndex + 1].title !== "Read All" - ? headings[currentIndex + 1] + const nextSection = + currentIndex < sections.length - 1 && + sections[currentIndex + 1].id !== READ_ALL_ID + ? sections[currentIndex + 1] : undefined; return (
- {prevHeading && ( - + {prevSection && ( +
- - - +
Previous
-
{prevHeading.title}
+
{prevSection.title}
)}
- {nextHeading && ( - + {nextSection && ( +
Next
-
{nextHeading.title}
+
{nextSection.title}
- - - +
)}
); -}; +} + +function createSections(sections: Section[]) { + return [ + { + id: READ_ALL_ID, + title: READ_ALL_TITLE, + Content() { + return ( + <> + {sections.map(({ id, title, Content: SectionContent }) => ( +
+

{title}

+ +
+ ))} + + ); + }, + }, + ...sections, + ]; +} + +function Arrow({ direction }: { direction: "left" | "right" }) { + return ( + + + + ); +} diff --git a/components/playground.tsx b/components/playground.tsx index 1d318680..5a417969 100644 --- a/components/playground.tsx +++ b/components/playground.tsx @@ -11,9 +11,6 @@ import AltTab, { metadata as altTabEventMetadata, } from "../content/playground/alt-tab.event.mdx"; -import ReadAll, { - metadata as readAllOrganizedContentMetadata, -} from "../content/playground/constitution/read-all.organized-content.mdx"; import Name, { metadata as nameOrganizedContentMetadata, } from "../content/playground/constitution/name.organized-content.mdx"; @@ -56,14 +53,13 @@ const events = [ ]; const constitution = [ - { content: , ...readAllOrganizedContentMetadata }, - { content: , ...nameOrganizedContentMetadata }, - { content: , ...purposeOrganizedContentMetadata }, - { content: , ...membershipOrganizedContentMetadata }, - { content: , ...officersOrganizedContentMetadata }, - { content: , ...dutiesOrganizedContentMetadata }, + { Content: Name, ...nameOrganizedContentMetadata }, + { Content: Purpose, ...purposeOrganizedContentMetadata }, + { Content: Membership, ...membershipOrganizedContentMetadata }, + { Content: Officers, ...officersOrganizedContentMetadata }, + { Content: Duties, ...dutiesOrganizedContentMetadata }, { - content: , + Content: ExecutiveCouncil, ...executiveCouncilOrganizedContentMetadata, }, ]; @@ -165,28 +161,17 @@ export function TeamMemberCardDemo() { export function OrganizedContentDemo() { const sections = constitution; - const [index, setIndex] = useState(0); + const [id, setId] = useState(sections[0].id); - function FakeLink({ className, url, children }: LinkProps) { + function FakeLink({ className, id, children }: LinkProps) { return ( -
{ - const target = sections.findIndex((section) => section.url === url); - - if (target >= 0) { - setIndex(target); - } - }} - > +
setId(id)}> {children}
); } return ( - - {sections[index].content} - + ); } diff --git a/content/playground/constitution/duties-of-officers.organized-content.mdx b/content/playground/constitution/duties-of-officers.organized-content.mdx index 230517c2..72f38bc4 100644 --- a/content/playground/constitution/duties-of-officers.organized-content.mdx +++ b/content/playground/constitution/duties-of-officers.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "5. Duties of Officers", - url: "5" + id: "duties-of-officers" }; The duties of the President shall be: diff --git a/content/playground/constitution/executive-council.organized-content.mdx b/content/playground/constitution/executive-council.organized-content.mdx index e33ae598..3c1f3cfe 100644 --- a/content/playground/constitution/executive-council.organized-content.mdx +++ b/content/playground/constitution/executive-council.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "6. Executive Council", - url: "6" + id: "executive-council" }; The Executive Council shall consist of the present officers of the Club and the Faculty Advisor (as a non-voting member) and has the power to run the affairs of this club within the limits of this constitution. This includes the power to overrule or issue directions to any officer. diff --git a/content/playground/constitution/membership.organized-content.mdx b/content/playground/constitution/membership.organized-content.mdx index 4d1dee0c..fecf3b31 100644 --- a/content/playground/constitution/membership.organized-content.mdx +++ b/content/playground/constitution/membership.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "3. Membership", - url: "3" + id: "membership" }; In compliance with MathSoc regulations and in recognition of the club being primarily targeted at undergraduate students, full membership is open to all Social Members of the Mathematics Society and restricted to the same. diff --git a/content/playground/constitution/name.organized-content.mdx b/content/playground/constitution/name.organized-content.mdx index f5b03854..c594f729 100644 --- a/content/playground/constitution/name.organized-content.mdx +++ b/content/playground/constitution/name.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "1. Name", - url: "1" + id: "name" }; The name of this organization shall be the "Computer Science Club of the University of Waterloo". diff --git a/content/playground/constitution/officers.organized-content.mdx b/content/playground/constitution/officers.organized-content.mdx index 945afd57..efa806d5 100644 --- a/content/playground/constitution/officers.organized-content.mdx +++ b/content/playground/constitution/officers.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "4. Officers", - url: "4" + id: "officers" }; The officers of the Club shall be: diff --git a/content/playground/constitution/purpose.organized-content.mdx b/content/playground/constitution/purpose.organized-content.mdx index 5b5082cc..904ad97c 100644 --- a/content/playground/constitution/purpose.organized-content.mdx +++ b/content/playground/constitution/purpose.organized-content.mdx @@ -1,6 +1,6 @@ export const metadata = { title: "2. Purpose", - url: "2" + id: "purpose" }; The Club is organized and will be operated exclusively for educational and scientific purposes in furtherance of: diff --git a/content/playground/constitution/read-all.organized-content.mdx b/content/playground/constitution/read-all.organized-content.mdx deleted file mode 100644 index 934388b8..00000000 --- a/content/playground/constitution/read-all.organized-content.mdx +++ /dev/null @@ -1,6 +0,0 @@ -export const metadata = { - title: "Read All", - url: "0" -}; - -You can leave readall blank, it is auto generated. \ No newline at end of file diff --git a/next-env.d.ts b/next-env.d.ts index 662b0751..e5f0d934 100644 --- a/next-env.d.ts +++ b/next-env.d.ts @@ -54,7 +54,7 @@ declare module "*.organized-content.mdx" { interface OrganizedContentMetadata { title: string; - url: string; + id: string; } const ReactComponent: ComponentType;