Skip to content

Commit

Permalink
Convert website to typescript
Browse files Browse the repository at this point in the history
  • Loading branch information
Zack Spencer authored and Zack Spencer committed Jan 23, 2020
1 parent 8523321 commit b1364f7
Show file tree
Hide file tree
Showing 19 changed files with 155 additions and 66 deletions.
6 changes: 6 additions & 0 deletions src/@types/typography-theme-lincoln.d.ts
@@ -0,0 +1,6 @@
declare module 'typography-theme-lincoln' {
import { TypographyOptions } from 'typography';
const Theme: TypographyOptions;

export = Theme;
}
2 changes: 2 additions & 0 deletions src/aws-exports.d.ts
@@ -0,0 +1,2 @@
declare const awsmobile: any;
export = awsmobile;
10 changes: 8 additions & 2 deletions src/components/Details.js → src/components/Details.tsx
@@ -1,10 +1,16 @@
import React from 'react';
import { Link } from 'gatsby';
import { getCurrentUser } from '../utils/auth';
import usePrivateRoute from '../utils/usePrivateRoute';

export default function Details() {
interface Props {
path: string;
}

export default function Details(props: Props) {
usePrivateRoute();
const user = getCurrentUser();
console.log('user:', user);
console.log('user:', user); // tslint:disable-line:no-console
return (
<div>
<h1>Profile Details</h1>
Expand Down
15 changes: 0 additions & 15 deletions src/components/Error.js

This file was deleted.

19 changes: 19 additions & 0 deletions src/components/Error.tsx
@@ -0,0 +1,19 @@
// https://github.com/wesbos/dump
import React from 'react';

interface Props {
[key: string]: any;
}

export default function Error(props: Props) {
return (
<div>
{Object.entries(props).map(([err, val]) => (
<pre key={err}>
<strong>{err}: </strong>
{JSON.stringify(val, undefined, ' ')}
</pre>
))}
</div>
);
}
12 changes: 8 additions & 4 deletions src/components/Header.js → src/components/Header.tsx
Expand Up @@ -6,9 +6,12 @@ import { rhythm } from '../utils/typography';
import { navigate } from '@reach/router';

import { logout, isLoggedIn } from '../utils/auth';
// import { Auth } from 'aws-amplify';

export default function Header({ siteTitle }) {
interface Props {
siteTitle: string;
}

export default function Header({ siteTitle }: Props) {
return (
<>
<Link to="/">
Expand All @@ -27,8 +30,9 @@ export default function Header({ siteTitle }) {
const { Auth } = await import('aws-amplify');

Auth.signOut()
.then(logout(() => navigate('/backend')))
.catch(err => console.log('eror:', err));
.then(() => logout(() => navigate('/backend')))
// tslint:disable-next-line:no-console
.catch((err: string) => console.log('eror:', err));
}}
css={css`
margin-top: ${rhythm(1.5)};
Expand Down
11 changes: 10 additions & 1 deletion src/components/Home.js → src/components/Home.tsx
@@ -1,7 +1,16 @@
import React from 'react';
import { Link } from 'gatsby';
import usePrivateRoute from '../utils/usePrivateRoute';

export default function Home() {
interface Props {
path: string;
}

export default function Home(props: Props) {
const loggedIn = usePrivateRoute();
if (!loggedIn) {
return null;
}
return (
<div>
<h1>Home</h1>
Expand Down
14 changes: 12 additions & 2 deletions src/components/Layout.js → src/components/Layout.tsx
Expand Up @@ -7,8 +7,18 @@ import { rhythm } from '../utils/typography';

import Header from './Header';

export default function Layout({ children }) {
const data = useStaticQuery(graphql`
interface LayoutData {
site: {
siteMetadata: {
title: string;
description: string;
author: string;
};
};
}

export default function Layout({ children }: React.PropsWithChildren<{}>) {
const data: LayoutData = useStaticQuery(graphql`
query SiteTitleQuery {
site {
siteMetadata {
Expand Down
14 changes: 9 additions & 5 deletions src/components/Login.js → src/components/Login.tsx
@@ -1,11 +1,14 @@
import React from 'react';
import React, { useState } from 'react';
import { navigate } from '@reach/router';
import { setUser, isLoggedIn } from '../utils/auth';
import Error from './Error';
// import { Auth } from 'aws-amplify';
import { useState } from 'react';

export default function Login() {
interface Props {
path: string;
}

export default function Login(props: Props) {
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState(null);
Expand All @@ -23,7 +26,7 @@ export default function Login() {
navigate('/backend/home');
} catch (err) {
setError(err);
console.log('error...: ', err);
console.log('error...: ', err); // tslint:disable-line:no-console
}
};

Expand Down Expand Up @@ -57,7 +60,8 @@ export default function Login() {
);
}

const styles = {
// TODO: remove any typing
const styles: any = {
input: {
height: 40,
margin: '10px 0px',
Expand Down
12 changes: 0 additions & 12 deletions src/components/PrivateRoute.js

This file was deleted.

File renamed without changes.
5 changes: 2 additions & 3 deletions src/pages/backend.js → src/pages/backend.tsx
Expand Up @@ -4,14 +4,13 @@ import Layout from '../components/Layout';
import Details from '../components/Details';
import Home from '../components/Home';
import Login from '../components/Login';
import PrivateRoute from '../components/PrivateRoute';

export default function Backend() {
return (
<Layout>
<Router>
<PrivateRoute path="/backend/home" component={Home} />
<PrivateRoute path="/backend/profile" component={Details} />
<Home path="/backend/home" />
<Details path="/backend/profile" />
<Login path="/backend" />
</Router>
</Layout>
Expand Down
25 changes: 23 additions & 2 deletions src/pages/index.js → src/pages/index.tsx
Expand Up @@ -4,11 +4,32 @@ import { Link, graphql } from 'gatsby';

import Layout from '../components/Layout';

import Amplify from '@aws-amplify/core';
import Amplify from 'aws-amplify';
import config from '../aws-exports';
Amplify.configure(config);

export default function IndexPage({ data }) {
interface Query {
allMdx: {
totalCount: number;
edges: {
node: {
id: string;
frontmatter: {
title: string;
};
fields: {
slug: string;
};
};
}[];
};
}

interface Props {
data: Query;
}

export default function IndexPage({ data }: Props) {
return (
<Layout>
<h1>A Website</h1>
Expand Down
@@ -1,13 +1,13 @@
import React, { useReducer } from 'react';
import React, { useReducer, Reducer } from 'react';
import { css } from '@emotion/core';
import TodoItem from './TodoItem';
import TodoItem, { Todo } from './TodoItem';

function initTodos(initialTodos) {
function initTodos(initialTodos: string[]): Todo[] {
const todos = initialTodos != null ? initialTodos : ['Make a Todo'];
return todos.map(e => ({ text: e }));
}

function mergeTodos(todos, idx) {
function mergeTodos(todos: Todo[], idx: number): Todo[] {
if (idx < 0 || idx >= todos.length - 1) {
return todos;
}
Expand All @@ -22,7 +22,8 @@ function mergeTodos(todos, idx) {
return newTodos;
}

function todoReducer(todos, action) {
// TODO: fix type of action.
function todoReducer(todos: Todo[], action: any): Todo[] {
const idx = action.index;
switch (action.type) {
case 'SET_TODO': {
Expand Down Expand Up @@ -70,8 +71,16 @@ const todoAppCss = css`
}
`;

export default function TodoApp({ initialTodos }) {
const [todos, dispatch] = useReducer(todoReducer, initialTodos, initTodos);
interface Props {
initialTodos: string[];
}

export default function TodoApp({ initialTodos }: Props) {
const [todos, dispatch] = useReducer<Reducer<Todo[], any>, string[]>(
todoReducer,
initialTodos,
initTodos
);
const todoItems = todos.map((todo, idx) => {
return (
<TodoItem
Expand Down
@@ -1,27 +1,29 @@
import React, { useEffect, useRef } from 'react';
import { css } from '@emotion/core';

function todoItemOnKeyDown(dispatch) {
function todoItemOnKeyDown(
dispatch: (action: any) => void
): React.KeyboardEventHandler<HTMLInputElement> {
return e => {
if (e.key === 'Enter') {
dispatch({
type: 'SPLIT_TODO',
start: e.target.selectionStart,
end: e.target.selectionEnd,
start: e.currentTarget.selectionStart,
end: e.currentTarget.selectionEnd,
});
} else if (
e.key === 'Backspace' &&
e.target.selectionStart === 0 &&
e.target.selectionEnd === 0
e.currentTarget.selectionStart === 0 &&
e.currentTarget.selectionEnd === 0
) {
e.preventDefault();
dispatch({
type: 'MERGE_PREV_TODO',
});
} else if (
e.key === 'Delete' &&
e.target.selectionStart === e.target.value.length &&
e.target.selectionEnd === e.target.value.length
e.currentTarget.selectionStart === e.currentTarget.value.length &&
e.currentTarget.selectionEnd === e.currentTarget.value.length
) {
e.preventDefault();
dispatch({
Expand Down Expand Up @@ -83,8 +85,19 @@ const textInputCss = css`
}
`;

export default function TodoItem({ todo, dispatch }) {
const textInput = useRef();
export interface Todo {
text: string;
isDone?: boolean;
focus?: number;
}

interface Props {
todo: Todo;
dispatch: (action: any) => void;
}

export default function TodoItem({ todo, dispatch }: Props) {
const textInput = useRef<HTMLInputElement>(null);
useEffect(() => {
if (todo.focus != null && textInput.current != null) {
textInput.current.focus();
Expand Down
Expand Up @@ -4,7 +4,7 @@ date: '2020-01-18'
lead: 'In which we explain some code which exists to explain other code'
---

import TodoApp from '../../2019/12/TodoApp.js';
import TodoApp from '../../2019/12/TodoApp';

To demo MDX, I wrote my own little Todo App, which you can see here:

Expand Down
7 changes: 4 additions & 3 deletions src/utils/auth.js → src/utils/auth.ts
@@ -1,11 +1,11 @@
const isBrowser = typeof window !== `undefined`;

export const setUser = user =>
export const setUser = (user: {}) =>
(window.localStorage.gatsbyUser = JSON.stringify(user));

const getUser = () => {
if (window.localStorage.gatsbyUser) {
let user = JSON.parse(window.localStorage.gatsbyUser);
const user = JSON.parse(window.localStorage.gatsbyUser);
return user ? user : {};
}
return {};
Expand All @@ -16,11 +16,12 @@ export const isLoggedIn = () => {

const user = getUser();
if (user) return !!user.username;
return false;
};

export const getCurrentUser = () => isBrowser && getUser();

export const logout = callback => {
export const logout: (callback: () => any) => void = callback => {
if (!isBrowser) return;
setUser({});
callback();
Expand Down
File renamed without changes.
13 changes: 13 additions & 0 deletions src/utils/usePrivateRoute.ts
@@ -0,0 +1,13 @@
import { navigate } from '@reach/router';
import { isLoggedIn } from '../utils/auth';
import { useEffect } from 'react';

export default function usePrivateRoute(): boolean {
const shouldStay = isLoggedIn();
useEffect(() => {
if (!shouldStay) {
navigate('/');
}
}, [shouldStay]);
return shouldStay;
}

0 comments on commit b1364f7

Please sign in to comment.