This repository has been archived on 2022-06-22. You can view files and clone it, but cannot push or open issues or pull requests.
usaco-guide/src/components/markdown/Problems.tsx
2020-06-27 15:00:00 -07:00

118 lines
4.3 KiB
TypeScript

import * as React from 'react';
import { Problem } from '../../../content/models';
type ProblemsListComponentProps = {
title?: string;
children?: React.ReactChildren;
problems: Problem[];
};
export function ProblemsListComponent(props: ProblemsListComponentProps) {
return (
<div className="flex flex-col">
<div className="-my-2 py-2 overflow-x-auto sm:-mx-6 sm:px-6 lg:-mx-8 lg:px-8">
<div className="align-middle inline-block min-w-full shadow overflow-hidden sm:rounded-lg border-b border-gray-200">
<table className="min-w-full no-markdown">
<thead>
<tr>
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Source
</th>
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50" />
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Problem Name
</th>
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50 text-left text-xs leading-4 font-medium text-gray-500 uppercase tracking-wider">
Difficulty
</th>
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50" />
<th className="px-6 py-3 border-b border-gray-200 bg-gray-50" />
</tr>
</thead>
<tbody className="table-alternating-stripes">
{props.problems.map(problem => (
<ProblemComponent problem={problem} />
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
type ProblemComponentProps = {
problem: Problem;
};
export function ProblemComponent(props: ProblemComponentProps) {
const difficultyClasses = {
Intro: 'bg-teal-100 text-teal-800',
Easy: 'bg-yellow-100 text-yellow-800',
Normal: 'bg-green-100 text-green-800',
Hard: 'bg-purple-100 text-purple-800',
'Very Hard': 'bg-red-100 text-red-800',
Insane: 'bg-blue-100 text-blue-800',
};
const [showTags, setShowTags] = React.useState(false);
const { problem } = props;
return (
<tr>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 text-gray-500 font-medium">
{problem.source}
</td>
<td className="pl-6 w-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
{problem.starred && (
<svg
className="h-6 w-6 text-blue-700"
fill="currentColor"
viewBox="0 0 20 20"
>
<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"></path>
</svg>
)}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-sm leading-5 font-medium text-gray-900">
<a href={problem.url}>{problem.name}</a>
</td>
<td className="px-6 py-4 whitespace-no-wrap leading-5">
{problem.difficulty && (
<span
className={
'px-2 inline-flex text-xs leading-5 font-semibold rounded-full ' +
difficultyClasses[problem.difficulty]
}
>
{problem.difficulty}
</span>
)}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-right text-sm leading-5 font-medium">
{!showTags && (
<a
href="#"
className="text-indigo-600 hover:text-indigo-900"
onClick={e => {
e.preventDefault();
setShowTags(true);
}}
>
Show Tags
</a>
)}
{showTags &&
(problem.tags && problem.tags.length
? problem.tags.join(', ')
: 'None')}
</td>
<td className="px-6 py-4 whitespace-no-wrap text-right text-sm leading-5 font-medium">
{/*{props.children}*/}
<a href="#" className="text-indigo-600 hover:text-indigo-900">
Show Solution
</a>
</td>
</tr>
);
}