lots of code refactors

This commit is contained in:
Nathan Wang 2020-07-17 16:23:58 -07:00
parent 6673aca3bf
commit 6d5c0c6b9e
33 changed files with 349 additions and 338 deletions

View file

@ -1,5 +1,7 @@
.cache
package.json
package-lock.json
yarn.lock
public
content
content
docs
static

View file

@ -9,8 +9,8 @@ As much as possible, please try to keep the markdown files independent of the fr
## Documentation
- To get this site running locally, refer to the [Front End Documentation](Front%20End%20Documentation.md).
- For information regarding Content Writing, refer to the [Content Documentation](Content%20Documentation.md).
- To get this site running locally, refer to the [Front End Documentation](docs/Front%20End%20Documentation.md).
- For information regarding Content Writing, refer to the [Content Documentation](docs/Content%20Documentation.md).
## Tech Stack

View file

@ -1,5 +1,7 @@
## Content Formatting Documentation
**Note:** It is highly recommended to [run a local version of the site](Front%20End%20Documentation.md) in order to view your changes.
All modules are written in [Markdown](https://www.markdownguide.org/cheat-sheet/). There are special additions to the markdown that we have added to this site.
These special additions are still under development, so they may change frequently.
If you are confused about something, or if there's a certain feature that you want to add, reach out to Nathan Wang.

View file

@ -1,9 +1,9 @@
import * as React from 'react';
import { ModuleInfo } from '../models/module';
import { SECTION_LABELS } from '../../content/ordering';
import SlideoverForm from './Slideover/SlideoverForm';
import { ModuleInfo } from '../../models/module';
import { SECTION_LABELS } from '../../../content/ordering';
import SlideoverForm from './SlideoverForm';
import { useState } from 'react';
import useStickyState from '../hooks/useStickyState';
import useStickyState from '../../hooks/useStickyState';
// Warning: this file is insanely messy. This should be rewritten soon :)

View file

@ -1,6 +1,6 @@
import * as React from 'react';
export default function Dots({ count, color, totalCount }) {
export default function ModuleFrequencyDots({ count, color, totalCount }) {
const emptyCircle = 'text-gray-300';
return (
<>

View file

@ -13,17 +13,17 @@ import MODULE_ORDERING, {
Category,
SECTION_LABELS,
} from '../../../content/ordering';
import Dots from '../Dots';
import ContactUsSlideover from '../ContactUsSlideover';
import ModuleFrequencyDots from './ModuleFrequencyDots';
import ContactUsSlideover from '../ContactUsSlideover/ContactUsSlideover';
import MarkCompleteButton from './MarkCompleteButton';
import ModuleConfetti from './ModuleConfetti';
import TextTooltip from '../tooltip/TextTooltip';
import TextTooltip from '../Tooltip/TextTooltip';
import UserDataContext, { UserLang } from '../../context/UserDataContext';
import { NavLinkGroup, SidebarNav } from './SidebarNav/SidebarNav';
import { graphqlToModuleLinks } from '../../utils';
import ModuleLayoutContext from '../../context/ModuleLayoutContext';
import TableOfContentsSidebar from './TableOfContentsSidebar';
import TableOfContentsBlock from './TableOfContentsBlock';
import TableOfContentsSidebar from './TableOfContents/TableOfContentsSidebar';
import TableOfContentsBlock from './TableOfContents/TableOfContentsBlock';
const Frequency = ({ frequency }: { frequency: ModuleFrequency }) => {
const textColors = [
@ -59,7 +59,11 @@ const Frequency = ({ frequency }: { frequency: ModuleFrequency }) => {
<span
className={`inline-flex items-center font-medium ${textColors[frequency]}`}
>
<Dots count={frequency} totalCount={4} color={circleColors[frequency]} />
<ModuleFrequencyDots
count={frequency}
totalCount={4}
color={circleColors[frequency]}
/>
<TextTooltip position="bottom" content={hints[frequency]}>
{labels[frequency]}
</TextTooltip>

View file

@ -1,6 +1,5 @@
import * as React from 'react';
import { ModuleLinkInfo } from '../../../models/module';
import { Link } from 'gatsby';
import ItemLink from './ItemLink';
import Accordion from './Accordion';
import MODULE_ORDERING, { Category } from '../../../../content/ordering';

View file

@ -0,0 +1,26 @@
import * as React from 'react';
import { TOCHeading } from '../../../models/module';
import genLinksFromTOCHeadings from './genLinksFromTOCHeadings';
const TableOfContentsBlock = ({
tableOfContents,
}: {
tableOfContents: TOCHeading[];
}) => {
let links = genLinksFromTOCHeadings(
tableOfContents,
_ =>
'block mb-2 transition duration-150 ease-in-out text-gray-600 hover:underline hover:text-blue-600'
);
return (
<div>
<h2 className="uppercase text-gray-500 font-bold mt-8 mb-3 tracking-wider">
Table of Contents
</h2>
{links}
<hr className="mt-6 mb-2" />
</div>
);
};
export default TableOfContentsBlock;

View file

@ -0,0 +1,37 @@
import * as React from 'react';
import { TOCHeading } from '../../../models/module';
import { Link } from 'gatsby';
import { useActiveHash } from '../../../hooks/useActiveHash';
import { useMemo } from 'react';
import genLinksFromTOCHeadings from './genLinksFromTOCHeadings';
const TableOfContentsSidebar = ({
tableOfContents,
}: {
tableOfContents: TOCHeading[];
}) => {
const hashes = useMemo(() => tableOfContents.map(heading => heading.slug), [
tableOfContents,
]);
const activeHash = useActiveHash(hashes, '10px 0px 0px 0px');
let links = genLinksFromTOCHeadings(
tableOfContents,
heading =>
'block mb-1 text-sm transition duration-150 ease-in-out ' +
(activeHash === heading.slug
? 'underline text-blue-600'
: 'text-gray-600 hover:underline hover:text-blue-600')
);
return (
<div className="sticky" style={{ top: '2.5rem' }}>
<h2 className="uppercase text-gray-500 font-bold mb-4 text-sm tracking-wider">
Table of Contents
</h2>
{links}
</div>
);
};
export default TableOfContentsSidebar;

View file

@ -0,0 +1,44 @@
import { TOCHeading } from '../../../models/module';
import * as React from 'react';
import { Link } from 'gatsby';
export default function genLinksFromTOCHeadings(
headings: TOCHeading[],
getClasses: (heading: TOCHeading) => string
) {
let indentationLevels = ['0', '1.5rem', '3rem', '4.5rem'];
let links: React.ReactNode[] = [];
let curDepth = -1;
let indentIdx = 0;
headings.forEach((heading, idx) => {
if (curDepth === -1) curDepth = heading.depth;
if (heading.depth > curDepth) {
indentIdx++;
} else if (heading.depth < curDepth) {
indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth));
}
curDepth = heading.depth;
links.push(
<Link
key={heading.slug}
to={'#' + heading.slug}
className={getClasses(heading)}
style={{
marginLeft: indentationLevels[indentIdx],
marginTop:
indentIdx === 0 &&
((idx !== 0 && headings[idx - 1].depth > heading.depth) ||
(idx !== headings.length - 1 &&
headings[idx + 1].depth > heading.depth))
? '1rem'
: indentIdx === 0
? '0.5rem'
: 0,
}}
>
{heading.value}
</Link>
);
});
return links;
}

View file

@ -1,60 +0,0 @@
import * as React from 'react';
import { TOCHeading } from '../../models/module';
import { Link } from 'gatsby';
import { useActiveHash } from '../../hooks/useActiveHash';
import { useMemo } from 'react';
// lol this file is basically idential to the sidebar file... should consolidate
const TableOfContentsBlock = ({
tableOfContents,
}: {
tableOfContents: TOCHeading[];
}) => {
let links = [];
let curDepth = -1;
let indentIdx = 0;
let indent = ['0', '1.5rem', '3rem', '4.5rem'];
tableOfContents.forEach((heading, idx) => {
if (curDepth === -1) curDepth = heading.depth;
if (heading.depth > curDepth) {
indentIdx++;
} else if (heading.depth < curDepth) {
indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth));
}
curDepth = heading.depth;
links.push(
<Link
key={heading.slug}
to={'#' + heading.slug}
className="block mb-2 transition duration-150 ease-in-out text-gray-600 hover:underline hover:text-blue-600"
style={{
marginLeft: indent[indentIdx],
marginTop:
indentIdx === 0 &&
((idx !== 0 && tableOfContents[idx - 1].depth > heading.depth) ||
(idx !== tableOfContents.length - 1 &&
tableOfContents[idx + 1].depth > heading.depth))
? '1rem'
: indentIdx === 0
? '0.5rem'
: 0,
}}
>
{heading.value}
</Link>
);
});
return (
<div>
<h2 className="uppercase text-gray-500 font-bold mt-8 mb-3 tracking-wider">
Table of Contents
</h2>
{links}
<hr className="mt-6 mb-2" />
</div>
);
};
export default TableOfContentsBlock;

View file

@ -1,67 +0,0 @@
import * as React from 'react';
import { TOCHeading } from '../../models/module';
import { Link } from 'gatsby';
import { useActiveHash } from '../../hooks/useActiveHash';
import { useMemo } from 'react';
const TableOfContentsSidebar = ({
tableOfContents,
}: {
tableOfContents: TOCHeading[];
}) => {
const hashes = useMemo(() => tableOfContents.map(heading => heading.slug), [
tableOfContents,
]);
const activeHash = useActiveHash(hashes, '10px 0px 0px 0px');
let links = [];
let curDepth = -1;
let indentIdx = 0;
let indent = ['0', '1.5rem', '3rem', '4.5rem'];
tableOfContents.forEach((heading, idx) => {
if (curDepth === -1) curDepth = heading.depth;
if (heading.depth > curDepth) {
indentIdx++;
} else if (heading.depth < curDepth) {
indentIdx = Math.max(0, indentIdx - (curDepth - heading.depth));
}
curDepth = heading.depth;
links.push(
<Link
key={heading.slug}
to={'#' + heading.slug}
className={
'block mb-1 text-sm transition duration-150 ease-in-out ' +
(activeHash === heading.slug
? 'underline text-blue-600'
: 'text-gray-600 hover:underline hover:text-blue-600')
}
style={{
marginLeft: indent[indentIdx],
marginTop:
indentIdx === 0 &&
((idx !== 0 && tableOfContents[idx - 1].depth > heading.depth) ||
(idx !== tableOfContents.length - 1 &&
tableOfContents[idx + 1].depth > heading.depth))
? '1rem'
: indentIdx === 0
? '0.5rem'
: 0,
}}
>
{heading.value}
</Link>
);
});
return (
<div className="sticky" style={{ top: '2.5rem' }}>
<h2 className="uppercase text-gray-500 font-bold mb-4 text-sm tracking-wider">
Table of Contents
</h2>
{links}
</div>
);
};
export default TableOfContentsSidebar;

View file

@ -0,0 +1,67 @@
import * as React from 'react';
import classNames from 'classnames';
const OffsetAnchor = ({ id, ...props }) => (
<span
id={id}
{...props}
className="absolute"
style={{ bottom: '100px', height: '2px' }}
/>
);
const HTMLComponents = {
table: ({ className, ...props }) => (
<table
{...props}
className={classNames(
'text-base border-gray-600 no-bottom-margin',
className
)}
/>
),
th: ({ className, ...props }) => (
<th {...props} className={classNames('border py-1 px-3', className)} />
),
td: ({ className, ...props }) => (
<td {...props} className={classNames('border py-1 px-3', className)} />
),
h1: ({ id, children, ...props }) => (
<h1
{...props}
className="leading-tight text-4xl font-bold mb-4 mt-12 text-gray-700"
>
<OffsetAnchor id={id} />
{children}
</h1>
),
h2: ({ id, children, ...props }) => (
<h2
className="leading-tight text-3xl font-bold mb-4 mt-12 text-gray-700 relative"
{...props}
>
<OffsetAnchor id={id} />
{children}
</h2>
),
h3: ({ id, children, ...props }) => (
<h3 {...props} className="leading-snug text-2xl font-semibold mb-4 mt-8">
<OffsetAnchor id={id} />
{children}
</h3>
),
h4: ({ id, children, ...props }) => (
<h4 {...props} className="leading-none text-xl font-semibold mb-2 mt-6">
<OffsetAnchor id={id} />
{children}
</h4>
),
p: props => <p {...props} className="mb-4" />,
'ol.li': ({ children, ...props }) => (
<li {...props}>
<div className="flex-1">{children}</div>
</li>
),
};
export default HTMLComponents;

View file

@ -1,8 +1,6 @@
import * as React from 'react';
import UserDataContext from '../../context/UserDataContext';
import { useContext } from 'react';
export const IncompleteSection = props => {
export const IncompleteSection = () => {
return (
<div className="p-4 bg-red-100 text-red-800 rounded">
<b>This section is not complete.</b> Feel free to file a request to

View file

@ -0,0 +1,33 @@
import * as React from 'react';
const Info = ({
children,
title,
}: {
children: React.ReactNode;
title: string;
}) => (
<div className="rounded-md bg-blue-50 p-4 mb-4 info-block">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3 flex-1">
<h3 className="info-block__heading">{title}</h3>
<div className="info-block__body no-bottom-margin">{children}</div>
</div>
</div>
</div>
);
export default Info;

View file

@ -0,0 +1,10 @@
import * as React from 'react';
const InlineCode = props => (
<code
{...props}
className="font-mono inline bg-gray-200 rounded px-1 py-05"
/>
);
export default InlineCode;

View file

@ -1,10 +1,11 @@
import * as React from 'react';
import UserDataContext from '../../context/UserDataContext';
import UserDataContext, {
LANGUAGE_LABELS,
} from '../../context/UserDataContext';
import { useContext } from 'react';
export const LanguageSection = props => {
const userSettings = useContext(UserDataContext);
let lang = userSettings.lang;
const { lang } = useContext(UserDataContext);
let sections = {};
React.Children.map(props.children, child => {
@ -13,24 +14,13 @@ export const LanguageSection = props => {
if (type === 'JavaSection') sections['java'] = child;
if (type === 'PySection') sections['py'] = child;
});
// props.children.forEach(child => {
// let type = child.props.mdxType;
// if (type === 'CPPSection') sections['cpp'] = child;
// if (type === 'JavaSection') sections['java'] = child;
// if (type === 'PySection') sections['py'] = child;
// });
const languages = {
cpp: 'C++',
java: 'Java',
py: 'Python',
};
if (lang === 'showAll') {
return (
<>
{Object.keys(sections).map(lang => (
<div key={lang}>
<p className="text-lg font-bold">{languages[lang]}</p>
<p className="text-lg font-bold">{LANGUAGE_LABELS[lang]}</p>
{sections[lang]}
</div>
))}
@ -43,11 +33,11 @@ export const LanguageSection = props => {
<div className="p-4 bg-red-100 text-red-800 rounded">
<b>
This section isn't yet available in your chosen language:{' '}
{languages[lang]}.
{LANGUAGE_LABELS[lang]}.
</b>{' '}
Please choose a different default language for now. Feel free to file a
request to add support for {languages[lang]} using the "Contact Us"
button.
request to add support for {LANGUAGE_LABELS[lang]} using the "Contact
Us" button.
</div>
);
}

View file

@ -1,12 +1,11 @@
import * as React from 'react';
import { MDXProvider } from '@mdx-js/react';
import SpoilerComponent from './SpoilerComponent';
import { ProblemsListComponent } from './Problems';
import { ResourceComponent, ResourcesListComponent } from './Resources';
import CodeBlock from './CodeBlock';
import classNames from 'classnames';
import Asterisk from '../tooltip/Asterisk';
import TextTooltip from '../tooltip/TextTooltip';
import Spoiler from './Spoiler';
import { ProblemsList } from './ProblemsList/ProblemsList';
import { Resource, ResourcesList } from './ResourcesList';
import CodeBlock from './CodeBlock/CodeBlock';
import Asterisk from '../Tooltip/Asterisk';
import TextTooltip from '../Tooltip/TextTooltip';
import {
CPPSection,
JavaSection,
@ -14,165 +13,31 @@ import {
PySection,
} from './LanguageSection';
import { IncompleteSection } from './IncompleteSection';
const OffsetAnchor = ({ id, ...props }) => (
<span
id={id}
{...props}
className="absolute"
style={{ bottom: '100px', height: '2px' }}
/>
);
import Info from './Info';
import Warning from './Warning';
import Optional from './Optional';
import InlineCode from './InlineCode';
import HTMLComponents from './HTMLComponents';
const components = {
'module-excerpt': props => <div {...props} />,
spoiler: SpoilerComponent,
'info-block': ({
children,
title,
}: {
children: React.ReactNode;
title: string;
}) => (
<div className="rounded-md bg-blue-50 p-4 mb-4 info-block">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-blue-400"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3 flex-1">
<h3 className="info-block__heading">{title}</h3>
<div className="info-block__body no-bottom-margin">{children}</div>
</div>
</div>
</div>
),
'warning-block': ({ children, title }) => (
<div className="rounded-md bg-yellow-50 p-4 mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-yellow-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-yellow-800">
Warning{title ? ': ' + title : '!'}
</h3>
<div className="mt-2 text-sm leading-5 text-yellow-700 no-bottom-margin">
{children}
</div>
</div>
</div>
</div>
),
'optional-content': ({
children,
title,
className,
}: {
children: React.ReactNode;
title?: string;
className?: string;
}) => (
<div
className={`bg-white overflow-hidden shadow rounded-lg border border-purple-400 mb-8`}
>
<div className="p-4 flex items-center font-medium text-purple-800 bg-purple-50">
<svg className="h-6 w-6 mr-3" fill="currentColor" viewBox="0 0 20 20">
<path d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM5.05 6.464A1 1 0 106.464 5.05l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM5 10a1 1 0 01-1 1H3a1 1 0 110-2h1a1 1 0 011 1zM8 16v-1h4v1a2 2 0 11-4 0zM12 14c.015-.34.208-.646.477-.859a4 4 0 10-4.954 0c.27.213.462.519.476.859h4.002z" />
</svg>
Optional{title ? `: ${title}` : ''}
</div>
<div className="p-4 pb-0">{children}</div>
</div>
),
'problems-list': ProblemsListComponent,
resources: ResourcesListComponent,
resource: ResourceComponent,
spoiler: Spoiler,
'info-block': Info,
'warning-block': Warning,
'optional-content': Optional,
'problems-list': ProblemsList,
resources: ResourcesList,
resource: Resource,
code: CodeBlock,
TextTooltip: TextTooltip,
inlineCode: props => (
<code
{...props}
className="font-mono inline bg-gray-200 rounded px-1 py-05"
/>
),
inlineCode: InlineCode,
LanguageSection: LanguageSection,
CPPSection: CPPSection,
JavaSection: JavaSection,
PySection: PySection,
IncompleteSection: IncompleteSection,
Asterisk: Asterisk,
table: ({ className, ...props }) => (
<table
{...props}
className={classNames(
'text-base border-gray-600 no-bottom-margin',
className
)}
/>
),
th: ({ className, ...props }) => (
<th {...props} className={classNames('border py-1 px-3', className)} />
),
td: ({ className, ...props }) => (
<td {...props} className={classNames('border py-1 px-3', className)} />
),
h1: ({ id, children, ...props }) => (
<h1
{...props}
className="leading-tight text-4xl font-bold mb-4 mt-12 text-gray-700"
>
<OffsetAnchor id={id} />
{children}
</h1>
),
h2: ({ id, children, ...props }) => (
<h2
className="leading-tight text-3xl font-bold mb-4 mt-12 text-gray-700 relative"
{...props}
>
<OffsetAnchor id={id} />
{children}
</h2>
),
h3: ({ id, children, ...props }) => (
<h3 {...props} className="leading-snug text-2xl font-semibold mb-4 mt-8">
<OffsetAnchor id={id} />
{children}
</h3>
),
h4: ({ id, children, ...props }) => (
<h4 {...props} className="leading-none text-xl font-semibold mb-2 mt-6">
<OffsetAnchor id={id} />
{children}
</h4>
),
p: props => <p {...props} className="mb-4" />,
'ol.li': ({ children, ...props }) => (
<li {...props}>
<div className="flex-1">{children}</div>
</li>
),
...HTMLComponents,
};
export default function ({ children }) {

View file

@ -0,0 +1,25 @@
import * as React from 'react';
const Optional = ({
children,
title,
className,
}: {
children: React.ReactNode;
title?: string;
className?: string;
}) => (
<div
className={`bg-white overflow-hidden shadow rounded-lg border border-purple-400 mb-8`}
>
<div className="p-4 flex items-center font-medium text-purple-800 bg-purple-50">
<svg className="h-6 w-6 mr-3" fill="currentColor" viewBox="0 0 20 20">
<path d="M11 3a1 1 0 10-2 0v1a1 1 0 102 0V3zM15.657 5.757a1 1 0 00-1.414-1.414l-.707.707a1 1 0 001.414 1.414l.707-.707zM18 10a1 1 0 01-1 1h-1a1 1 0 110-2h1a1 1 0 011 1zM5.05 6.464A1 1 0 106.464 5.05l-.707-.707a1 1 0 00-1.414 1.414l.707.707zM5 10a1 1 0 01-1 1H3a1 1 0 110-2h1a1 1 0 011 1zM8 16v-1h4v1a2 2 0 11-4 0zM12 14c.015-.34.208-.646.477-.859a4 4 0 10-4.954 0c.27.213.462.519.476.859h4.002z" />
</svg>
Optional{title ? `: ${title}` : ''}
</div>
<div className="p-4 pb-0">{children}</div>
</div>
);
export default Optional;

View file

@ -1,9 +1,9 @@
import * as React from 'react';
import Tooltip from './tooltip/Tooltip';
import { Problem } from '../../content/models';
import Tooltip from '../../Tooltip/Tooltip';
import { Problem } from '../../../../content/models';
import { useContext } from 'react';
import UserDataContext from '../context/UserDataContext';
import { NEXT_PROBLEM_STATUS, ProblemProgress } from '../models/problem';
import UserDataContext from '../../../context/UserDataContext';
import { NEXT_PROBLEM_STATUS, ProblemProgress } from '../../../models/problem';
export default function ProblemStatusCheckbox({
problem,

View file

@ -1,18 +1,18 @@
import * as React from 'react';
import { Problem } from '../../../content/models';
import Transition from '../Transition';
import Tooltip from '../tooltip/Tooltip';
import TextTooltip from '../tooltip/TextTooltip';
import { sourceTooltip } from './Resources';
import ProblemStatusCheckbox from '../ProblemStatusCheckbox';
import { Problem } from '../../../../content/models';
import Transition from '../../Transition';
import Tooltip from '../../Tooltip/Tooltip';
import TextTooltip from '../../Tooltip/TextTooltip';
import { sourceTooltip } from '../ResourcesList';
import ProblemStatusCheckbox from './ProblemStatusCheckbox';
type ProblemsListComponentProps = {
type ProblemsListProps = {
title?: string;
children?: React.ReactChildren;
problems: Problem[];
};
export function ProblemsListComponent(props: ProblemsListComponentProps) {
export function ProblemsList(props: ProblemsListProps) {
const [problem, setProblem] = React.useState(null);
const [showModal, setShowModal] = React.useState(false);
return (

View file

@ -1,11 +1,10 @@
import * as React from 'react';
import Dots from '../Dots';
import Tooltip from '../tooltip/Tooltip';
import TextTooltip from '../tooltip/TextTooltip';
import Tooltip from '../Tooltip/Tooltip';
import TextTooltip from '../Tooltip/TextTooltip';
import { useContext } from 'react';
import UserDataContext from '../../context/UserDataContext';
export function ResourcesListComponent(props) {
export function ResourcesList(props) {
const embedded = props.embedded;
return (
<div className="flex flex-col mb-4">
@ -91,7 +90,7 @@ export const sourceTooltip = {
'Old Gold': 'USACO Platinum did not exist prior to 2015-16.',
};
export function ResourceComponent(props) {
export function Resource(props) {
const userSettings = useContext(UserDataContext);
const source = props.source;

View file

@ -1,6 +1,6 @@
import * as React from 'react';
const SpoilerComponent = ({ children, title }) => {
const Spoiler = ({ children, title }) => {
const [show, setShow] = React.useState(false);
return (
@ -44,4 +44,4 @@ const SpoilerComponent = ({ children, title }) => {
);
};
export default SpoilerComponent;
export default Spoiler;

View file

@ -0,0 +1,31 @@
import * as React from 'react';
const Warning = ({ children, title }) => (
<div className="rounded-md bg-yellow-50 p-4 mb-4">
<div className="flex">
<div className="flex-shrink-0">
<svg
className="h-5 w-5 text-yellow-400"
viewBox="0 0 20 20"
fill="currentColor"
>
<path
fillRule="evenodd"
d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z"
clipRule="evenodd"
/>
</svg>
</div>
<div className="ml-3">
<h3 className="text-sm leading-5 font-medium text-yellow-800">
Warning{title ? ': ' + title : '!'}
</h3>
<div className="mt-2 text-sm leading-5 text-yellow-700 no-bottom-margin">
{children}
</div>
</div>
</div>
</div>
);
export default Warning;

View file

@ -5,6 +5,12 @@ import { ModuleProgress } from '../models/module';
import { ProblemProgress } from '../models/problem';
export type UserLang = 'showAll' | 'cpp' | 'java' | 'py';
export const LANGUAGE_LABELS: { [key in UserLang]: string } = {
showAll: 'All',
cpp: 'C++',
java: 'Java',
py: 'Python',
};
const UserDataContext = createContext<{
lang: UserLang;