Migrate project from JS+Flow to TypeScript

This commit is contained in:
Mitchell Simon 2019-09-02 21:53:03 -04:00
parent 60a557f918
commit 356b95579e
36 changed files with 3300 additions and 3058 deletions

View file

@ -1,21 +0,0 @@
// @flow
import React from 'react'
import './index.css'
type Props = {
href: string,
children: string
}
class ClearButton extends React.PureComponent<Props> {
render () {
return (
<a className='clear-button' href={this.props.href}>
{this.props.children}
</a>
)
}
}
export default ClearButton

View file

@ -0,0 +1,18 @@
import React from "react"
import "./index.css"
type Props = {
href: string
children: string
}
export default class ClearButton extends React.PureComponent<Props> {
public render() {
return (
<a className="clear-button" href={this.props.href}>
{this.props.children}
</a>
)
}
}

View file

@ -1,26 +0,0 @@
// @flow
import React from 'react'
import SmallText from '../SmallText'
import './index.css'
type Props = {}
class Header extends React.PureComponent<Props> {
render () {
return (
<div className='header-container'>
<h2>Mitchell J. F. Simon</h2>
<SmallText>
Software engineer;&nbsp;
<span style={{ display: 'inline-block' }}>
cloud-native web services and clients
</span>
</SmallText>
</div>
)
}
}
export default Header

View file

@ -0,0 +1,21 @@
import React from "react"
import SmallText from "../SmallText"
import "./index.css"
export default class Header extends React.PureComponent {
public render() {
return (
<div className="header-container">
<h2>Mitchell J. F. Simon</h2>
<SmallText>
Software engineer;&nbsp;
<span style={{ display: "inline-block" }}>
cloud-native web services and clients
</span>
</SmallText>
</div>
)
}
}

View file

@ -1,37 +0,0 @@
// @flow
import * as React from 'react'
import SmallText from '../../components/SmallText'
import './index.css'
type Props = {
title: string,
company: string,
timeSpan: string,
bullets: Array<string>
}
class Experience extends React.PureComponent<Props> {
listedBullets: Array<React.Element<string>>
constructor (props: Props) {
super(props)
this.listedBullets = this.props.bullets.map((bullet, index) => (
<li key={index}>{bullet}</li>
))
}
render () {
return (
<div className='job-container'>
<div className='job-title'>{this.props.title}</div>
<div className='job-company'>{this.props.company}</div>
<SmallText>{this.props.timeSpan}</SmallText>
<ul>{this.listedBullets}</ul>
</div>
)
}
}
export default Experience

View file

@ -0,0 +1,29 @@
import * as React from "react"
import SmallText from "../../components/SmallText"
import "./index.css"
type Props = {
title: string
company: string
timeSpan: string
bullets: string[]
}
export default class Experience extends React.PureComponent<Props> {
public render() {
return (
<div className="job-container">
<div className="job-title">{this.props.title}</div>
<div className="job-company">{this.props.company}</div>
<SmallText>{this.props.timeSpan}</SmallText>
<ul>{this.renderBullets()}</ul>
</div>
)
}
private renderBullets() {
return this.props.bullets.map((bullet, index) => (
<li key={index}>{bullet}</li>
))
}
}

View file

@ -1,88 +0,0 @@
// @flow
import * as React from 'react'
import { NavLink } from 'react-router-dom'
import FontAwesomeIcon from '@fortawesome/react-fontawesome'
import faBars from '@fortawesome/fontawesome-free-solid/faBars'
import './index.css'
import { routes } from '../../routes/routes.js'
const changeMenu = 800
type Props = {}
type State = {
showMenu: boolean
}
class Navbar extends React.Component<Props, State> {
buttons: Array<NavLink<string>>
constructor (props: Props) {
super(props)
if (window.innerWidth <= changeMenu) {
this.state = { showMenu: false }
} else {
this.state = { showMenu: true }
}
this.buttons = routes.map(route => (
<NavLink
key={route.name}
className='navbar-menu-button'
activeClassName='active-button'
exact={route.exact}
to={route.path}
onClick={this.closeMenu}
>
{route.name}
</NavLink>
))
}
isMobile = () => window.innerWidth <= changeMenu
closeMenu = () => {
window.scrollTo(0, 0)
if (this.isMobile()) {
this.setState({ showMenu: false })
}
}
toggleMenu = () => {
if (this.isMobile() || !this.state.showMenu) {
this.setState(prev => ({ showMenu: !prev.showMenu }))
}
}
render () {
let menuButton: ?React.Element<string>
if (this.isMobile()) {
menuButton = (
<div
className={
this.state.showMenu
? 'navbar-button navbar-button-closed'
: 'navbar-button'
}
onClick={this.toggleMenu}
>
<FontAwesomeIcon icon={faBars} />
</div>
)
}
return (
<div className='navbar'>
{menuButton}
{this.state.showMenu ? (
<div className='navbar-menu'>{this.buttons}</div>
) : null}
</div>
)
}
}
export default Navbar

View file

@ -0,0 +1,81 @@
import { faBars } from "@fortawesome/free-solid-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import * as React from "react"
import { NavLink } from "react-router-dom"
import { routes } from "../../routes/routes"
import "./index.css"
type State = {
showMenu: boolean
}
class Navbar extends React.Component<{}, State> {
constructor(props: {}) {
super(props)
this.state = { showMenu: !this.isMobile() }
}
public render() {
let menuButton: JSX.Element | null = null
if (this.isMobile()) {
menuButton = (
<div
className={
this.state.showMenu
? "navbar-button navbar-button-closed"
: "navbar-button"
}
onClick={this.toggleMenu}
>
<FontAwesomeIcon icon={faBars} />
</div>
)
}
return (
<div className="navbar">
{menuButton}
{this.state.showMenu ? (
<div className="navbar-menu">{this.renderButtons()}</div>
) : null}
</div>
)
}
private isMobile() {
const mobileMenuMaximum = 800
return window.innerWidth <= mobileMenuMaximum
}
private toggleMenu() {
if (this.isMobile() || !this.state.showMenu) {
this.setState(prev => ({ showMenu: !prev.showMenu }))
}
}
private renderButtons() {
return routes.map(route => (
<NavLink
key={route.name}
className="navbar-menu-button"
activeClassName="active-button"
exact={route.exact}
to={route.path}
onClick={this.closeMenu}
>
{route.name}
</NavLink>
))
}
private closeMenu() {
window.scrollTo(0, 0)
if (this.isMobile()) {
this.setState({ showMenu: false })
}
}
}
export default Navbar

View file

@ -1,42 +0,0 @@
// @flow
import * as React from 'react'
import ClearButton from '../../components/ClearButton'
import './index.css'
type Badge = {
imgUrl: string,
linkUrl: string,
alt: string
}
type Props = {
title: string,
children: string,
repoUrl: string,
badges: Array<Badge>
}
class Project extends React.PureComponent<Props> {
renderBadges = (badges: Array<Badge>) => {
return this.props.badges.map((badge, index) => (
<a className='project-badge' href={badge.linkUrl} key={index}>
<img src={badge.imgUrl} alt={badge.alt} />
</a>
))
}
render () {
return (
<div className='project-container'>
<h4>{this.props.title}</h4>
{this.renderBadges(this.props.badges)}
<p>{this.props.children}</p>
<ClearButton href={this.props.repoUrl}>Repository</ClearButton>
</div>
)
}
}
export default Project

View file

@ -0,0 +1,39 @@
import * as React from "react"
import ClearButton from "../../components/ClearButton"
import "./index.css"
type Badge = {
imgUrl: string
linkUrl: string
alt: string
}
type Props = {
title: string
children: string
repoUrl: string
badges: Badge[]
}
export default class Project extends React.PureComponent<Props> {
public render() {
return (
<div className="project-container">
<h4>{this.props.title}</h4>
{this.renderBadges(this.props.badges)}
<p>{this.props.children}</p>
<ClearButton href={this.props.repoUrl}>Repository</ClearButton>
</div>
)
}
private renderBadges(badges: Badge[]) {
return this.props.badges.map((badge, index) => (
<a className="project-badge" href={badge.linkUrl} key={index}>
<img src={badge.imgUrl} alt={badge.alt} />
</a>
))
}
}

View file

@ -1,16 +0,0 @@
// @flow
import React from 'react'
import './index.css'
type Props = {
children: string
}
class SmallText extends React.PureComponent<Props> {
render () {
return <div className='small-text'>{this.props.children}</div>
}
}
export default SmallText

View file

@ -0,0 +1,10 @@
// @flow
import React from "react"
import "./index.css"
export default class SmallText extends React.PureComponent {
public render() {
return <div className="small-text">{this.props.children}</div>
}
}