// This component has the wiki/manual/info
// Library import
import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import styled from 'styled-components'
// Config/component import
import colors from '../config/colors'
import pages from './Learn/MdxPages'
import { MdxStylesWrapper } from './Learn/MdxStylesWrapper'
import { Button, useMediaQuery } from '@mui/material'
import Draggable from './Interface/Draggable'
import Scaleable from './Interface/Scaleable'
import { paramsSelectors } from '../stores/paramsStore'
const { selectSinglePanelState } = paramsSelectors
//// Component Styling
// Main container for component
const InfoContainer = styled.div`
background: ${colors.gray};
color: ${colors.white};
padding: 0;
border-radius: 4px;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
display: ${(props) => (props.active ? 'flex' : 'none')};
flex-direction: row;
padding-top: 2.5em;
max-height: 100%;
height: 100%;
svg {
width: 25px;
height: 25px;
padding: 0;
fill: ${colors.white};
display: inline;
transition: 250ms all;
cursor: pointer;
}
a {
color: ${colors.yellow};
text-decoration: none;
}
@media (max-width: 1024px) {
right: 50%;
bottom: 50%;
transform: translate(50%, 50%);
overflow: hidden;
}
@media (max-width: 600px) {
position: fixed;
height: calc(100% - 10em);
width: 100%;
top: 10em;
left: 0;
transform: none;
}
hr {
margin: 1em 0 2em 0;
}
/* Fixes for inner MDX styles */
ol,
ul {
margin-inline-start: 2em;
}
ol li:before {
background: none;
}
.cls-1 {
stroke: white;
}
/* Fixes for contact form */
form {
color: white;
border: 1px solid white;
.MuiInputLabel-root {
color: white;
}
fieldset {
border-color: white;
}
}
`
// Left hand side list of available pages
// On mobile, this is replaced by a select drop down
const Drawer = styled.div`
width: 12em;
padding: 0.5em 0.5em 0 0.5em;
flex: 0 0 auto;
border-right: 2px solid ${colors.darkgray};
border-top: 2px solid ${colors.darkgray};
height: 100%;
flex: 0 0 auto;
hr {
border-top: 2px solid ${colors.darkgray};
}
@media (max-width: 600px) {
display: none;
}
`
// Buttons on left-hand side drawer
const DrawerButton = styled(Button)`
text-transform: capitalize;
line-height: 1;
display: block;
text-align: left;
background: none;
color: ${(props) => (props.active ? colors.lightblue : colors.white)};
border: none;
outline: none;
line-height: 2;
transition: 250ms;
padding: 0;
font-family: 'Lato', sans-serif;
opacity: ${(props) => (props.active ? 1 : 0.6)};
&:hover {
opacity: 1;
}
@media (max-width: 1024px) {
display: none;
}
&:active {
color: white;
}
`
const BodyContainerOuter = styled.div`
flex: 1;
`
// Container for main content
const BodyContainer = styled.div`
height: 100%;
max-height: 100%;
box-sizing: border-box;
overflow-y: auto;
padding: 1em 1em 1em 2em;
border-top: 2px solid ${colors.darkgray};
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background: #2b2b2b;
}
/* Handle */
::-webkit-scrollbar-thumb {
background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #999;
background-position: center center;
background-repeat: no-repeat, no-repeat;
background-size: 50%, 100%;
transition: 125ms all;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: url('${process.env.PUBLIC_URL}/icons/grip.png'), #f9f9f9;
background-position: center center;
background-repeat: no-repeat, no-repeat;
background-size: 50%, 100%;
}
img {
padding: 1em;
}
`
// // Yellow highlighted button to show interface element when going through tutorial
// const TutorialButton = styled.button`
// background: none;
// outline: none;
// box-sizing: border-box;
// border: 1px solid white;
// cursor: pointer;
// text-align: left;
// padding: 5px;
// width: calc(50% - 10px);
// margin: 5px;
// display: inline-block;
// color: ${colors.white};
// font-family: "Lato", sans-serif;
// padding: 10px;
// transition: 250ms all;
// &:hover {
// background: ${colors.yellow};
// color: ${colors.gray};
// }
// h3,
// p {
// padding: 0;
// margin: 0;
// }
// `;
// // Mobile only: drop down to select article instead of list of pages
// const PagesDropDown = styled(StyledDropDown)`
// position: absolute;
// top: 0;
// visibility: hidden;
// left: 50%;
// transform: translateX(-50%);
// @media (max-width: 1024px) {
// visibility: visible;
// }
// `;
// End styles
// // Tutorials
// const tutorialInfo = [
// {
// title: "Choropleth Maps",
// subtitle:
// "Explore counts and percentages of cases, deaths, hosipital beds, and testing data.",
// link: "choropleth-tutorial",
// },
// {
// title: "Hotspots",
// subtitle: "Find groups of counties and states affected by the virus.",
// link: "hotspot-tutorial",
// },
// {
// title: "Emerging Trends",
// subtitle: "Locate areas that will soon be significantly affected by COVID.",
// link: "emerging-tutorial",
// },
// {
// title: "Change Over Time",
// subtitle: "See the history of the virus by county and state.",
// link: "change-tutorial",
// },
// ];
/**
* Tutorial and information floating box panel.
*
* @category Components/Map
* @param {Object} props
* @param {number} props.defaultX - Default x position of panel
* @param {number} props.defaultY - Default y position of panel
* @param {number} props.defaultWidth - Default width of panel
* @param {number} props.defaultHeight - Default height of panel
* @param {number} props.minHeight - Minimum height of panel
* @param {number} props.minWidth - Minimum width of panel
* @component
*/
function InfoBox({
defaultX,
defaultY,
defaultWidth,
defaultHeight,
minHeight,
minWidth,
}){
const panelOpen = useSelector(selectSinglePanelState('tutorial'))
const [currentArticle, setCurrentArticle] = useState('release-notes')
const Content = pages[currentArticle]?.default
const isMobile = useMediaQuery('(max-width: 600px)')
const InfoboxContent = (
<InfoContainer active={panelOpen}>
<Drawer>
<DrawerButton
active={currentArticle === 'release-notes'}
onClick={() => setCurrentArticle('release-notes')}
>
Release Notes
</DrawerButton>
<DrawerButton
active={currentArticle === 'bug-report'}
onClick={() => setCurrentArticle('bug-report')}
>
Bug Report
</DrawerButton>
<hr />
<p>Tutorials</p>
{Object.keys(pages)
.filter(
(f) =>
[
'release-notes',
'stylesheet',
'bug-report',
].includes(f) === false
)
.map((slug, i) => (
<DrawerButton
active={currentArticle === slug}
onClick={() => setCurrentArticle(slug)}
>
{slug.replace(/-/g, ' ')}
</DrawerButton>
))}
</Drawer>
<BodyContainerOuter>
<BodyContainer>
<MdxStylesWrapper>
{!!Content && <Content />}
</MdxStylesWrapper>
</BodyContainer>
</BodyContainerOuter>
</InfoContainer>
)
if (isMobile) {
return InfoboxContent
}
return (
<Draggable
z={10}
title="tutorial"
defaultX={defaultX}
defaultY={defaultY}
>
<Scaleable
title="tutorial"
defaultWidth={defaultWidth}
defaultHeight={defaultHeight}
minHeight={minHeight}
minWidth={minWidth}
>
{InfoboxContent}
</Scaleable>
</Draggable>
)
}
export default InfoBox
Source