convert to Typescript

This commit is contained in:
Michael Fatemi 2021-04-10 13:57:07 -04:00
parent d257ef52ec
commit 7d8601c23c
16 changed files with 152 additions and 49 deletions

35
package-lock.json generated
View File

@ -1950,6 +1950,11 @@
"@types/node": "*" "@types/node": "*"
} }
}, },
"@types/history": {
"version": "4.7.8",
"resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.8.tgz",
"integrity": "sha512-S78QIYirQcUoo6UJZx9CSP0O2ix9IaeAXwQi26Rhr/+mg7qqPy8TzaxHSUut7eGjL8WmLccT7/MXf304WjqHcA=="
},
"@types/html-minifier-terser": { "@types/html-minifier-terser": {
"version": "5.1.1", "version": "5.1.1",
"resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz", "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz",
@ -2014,9 +2019,9 @@
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==" "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
}, },
"@types/node": { "@types/node": {
"version": "14.14.31", "version": "14.14.37",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.31.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.37.tgz",
"integrity": "sha512-vFHy/ezP5qI0rFgJ7aQnjDXwAMrG0KqqIH7tQG5PPv3BWBayOPIQNBjVc/P6hhdZfMx51REc6tfDNXHUio893g==" "integrity": "sha512-XYmBiy+ohOR4Lh5jE379fV2IU+6Jn4g5qASinhitfyO71b/sCo6MKsMLF5tc7Zf2CE8hViVQyYSobJNke8OvUw=="
}, },
"@types/normalize-package-data": { "@types/normalize-package-data": {
"version": "2.4.0", "version": "2.4.0",
@ -2053,6 +2058,25 @@
"csstype": "^3.0.2" "csstype": "^3.0.2"
} }
}, },
"@types/react-router": {
"version": "5.1.13",
"resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.13.tgz",
"integrity": "sha512-ZIuaO9Yrln54X6elg8q2Ivp6iK6p4syPsefEYAhRDAoqNh48C8VYUmB9RkXjKSQAJSJV0mbIFCX7I4vZDcHrjg==",
"requires": {
"@types/history": "*",
"@types/react": "*"
}
},
"@types/react-router-dom": {
"version": "5.1.7",
"resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.1.7.tgz",
"integrity": "sha512-D5mHD6TbdV/DNHYsnwBTv+y73ei+mMjrkGrla86HthE4/PVvL1J94Bu3qABU+COXzpL23T1EZapVVpwHuBXiUg==",
"requires": {
"@types/history": "*",
"@types/react": "*",
"@types/react-router": "*"
}
},
"@types/react-transition-group": { "@types/react-transition-group": {
"version": "4.4.1", "version": "4.4.1",
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.1.tgz",
@ -14097,6 +14121,11 @@
"is-typedarray": "^1.0.0" "is-typedarray": "^1.0.0"
} }
}, },
"typescript": {
"version": "4.2.4",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz",
"integrity": "sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg=="
},
"uncontrollable": { "uncontrollable": {
"version": "7.2.1", "version": "7.2.1",
"resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz", "resolved": "https://registry.npmjs.org/uncontrollable/-/uncontrollable-7.2.1.tgz",

View File

@ -7,6 +7,9 @@
"@testing-library/react": "^11.1.0", "@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10", "@testing-library/user-event": "^12.1.10",
"@types/bootstrap": "^5.0.12", "@types/bootstrap": "^5.0.12",
"@types/node": "^14.14.37",
"@types/react": "^17.0.3",
"@types/react-router-dom": "^5.1.7",
"bootstrap": "^4.6.0", "bootstrap": "^4.6.0",
"jquery": "^3.6.0", "jquery": "^3.6.0",
"popper.js": "^1.16.1", "popper.js": "^1.16.1",
@ -15,6 +18,7 @@
"react-dom": "^17.0.2", "react-dom": "^17.0.2",
"react-router-dom": "^5.2.0", "react-router-dom": "^5.2.0",
"react-scripts": "4.0.3", "react-scripts": "4.0.3",
"typescript": "^4.2.4",
"web-vitals": "^1.0.1" "web-vitals": "^1.0.1"
}, },
"scripts": { "scripts": {

View File

@ -1,2 +0,0 @@
const dev = process.env.NODE_ENV === 'development';
export const API_ENDPOINT = 'http://localhost/api';

4
src/api.ts Normal file
View File

@ -0,0 +1,4 @@
const dev = process.env.NODE_ENV === 'development';
export const API_ENDPOINT = 'http://localhost/api';
export const ION_AUTHORIZATION_ENDPOINT =
'https://ion.tjhsst.edu/oauth/authorize?response_type=code&client_id=ScL9QdZ9m3iGmHG11uznwABg4ZSkabQJan05ZYsk&scope=read&redirect_uri=http%3A%2F%2Flocalhost%3A5000%2Fauth%2Fion%2Fsuccess;';

View File

@ -1,7 +1,7 @@
import React from 'react'; import { FormEventHandler } from 'react';
const CreatePool = (props) => { const CreatePool = () => {
const onSubmit = (e) => { const onSubmit: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault(); e.preventDefault();
fetch(`${process.env.REACT_APP_API_ENDPOINT}/createPool`) fetch(`${process.env.REACT_APP_API_ENDPOINT}/createPool`)
@ -24,7 +24,7 @@ const CreatePool = (props) => {
<h1 className="form-title" style={{ fontFamily: 'Impact' }}> <h1 className="form-title" style={{ fontFamily: 'Impact' }}>
Create Pool Create Pool
</h1> </h1>
<label className="" for="title"> <label className="" htmlFor="title">
Pool Title:{' '} Pool Title:{' '}
</label> </label>
<input <input
@ -36,7 +36,7 @@ const CreatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="capacity"> <label className="" htmlFor="capacity">
Pool Capacity: Pool Capacity:
</label> </label>
<input <input
@ -48,7 +48,7 @@ const CreatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="pool_start"> <label className="" htmlFor="pool_start">
Start Time: Start Time:
</label> </label>
<input <input
@ -60,7 +60,7 @@ const CreatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="pool_end"> <label className="" htmlFor="pool_end">
End Time: End Time:
</label> </label>
<input <input
@ -72,17 +72,16 @@ const CreatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="title"> <label className="" htmlFor="title">
Pool Description: Pool Description:
</label> </label>
<textarea <textarea
type="text"
id="Pool-text" id="Pool-text"
name="Pool-text" name="Pool-text"
style={{ height: '200px' }} style={{ height: '200px' }}
className="form-control" className="form-control"
placeholder="Enter text here..." placeholder="Enter text here..."
></textarea> />
</div> </div>
<input <input

View File

@ -1,6 +1,4 @@
import React from 'react'; const Nav = () => {
const Nav = (props) => {
return ( return (
<nav className="navbar navbar-expand-lg navbar-dark bg-dark"> <nav className="navbar navbar-expand-lg navbar-dark bg-dark">
<button <button

View File

@ -1,7 +1,8 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect, FormEventHandler } from 'react';
import { useParams } from 'react-router';
const Pool = (props) => { const Pool = () => {
const id = props.match.params.id; const id = useParams<{ id: string }>().id;
const [state, setState] = useState({ const [state, setState] = useState({
pool_title: 'TJ Carpool', pool_title: 'TJ Carpool',
id: 1, id: 1,
@ -22,7 +23,7 @@ const Pool = (props) => {
} }
}); });
}; };
const onComment = (e) => { const onComment: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault(); e.preventDefault();
fetch(`${process.env.REACT_APP_API_ENDPOINT}/pool/comments`) fetch(`${process.env.REACT_APP_API_ENDPOINT}/pool/comments`)
@ -57,7 +58,6 @@ const Pool = (props) => {
<textarea <textarea
className="form-control" className="form-control"
id="comment" id="comment"
type="text"
placeholder="Enter comment here..." placeholder="Enter comment here..."
/> />
<input className="btn btn-primary" type="submit" value="Submit" /> <input className="btn btn-primary" type="submit" value="Submit" />

View File

@ -1,8 +1,11 @@
import React, { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { API_ENDPOINT } from '../api'; import { API_ENDPOINT } from '../api';
const Pools = (props) => { const maybePluralize = (count: number, noun: string, suffix = 's') =>
const [pools, setPools] = useState([ `${count} ${noun}${count !== 1 ? suffix : ''}`;
const Pools = () => {
const [pools, setPools] = useState<Carpool.Pool[]>([
/* /*
{ {
id: 1, id: 1,
@ -65,8 +68,6 @@ const Pools = (props) => {
}); });
}, []); }, []);
const maybePluralize = (count, noun, suffix = 's') =>
`${count} ${noun}${count !== 1 ? suffix : ''}`;
return ( return (
<div className="bg-dark" style={{ minHeight: '100vh' }}> <div className="bg-dark" style={{ minHeight: '100vh' }}>
<h1 <h1
@ -97,10 +98,10 @@ const Pools = (props) => {
style={{ backgroundColor: background }} style={{ backgroundColor: background }}
> >
<a href={'/Pool/' + pool.id} className="card-title"> <a href={'/Pool/' + pool.id} className="card-title">
{pool.pool_title} {pool.title}
</a> </a>
<p className="text-left"> <p className="text-left">
Capacity: {pool.participants.length} / {pool.capacity} Capacity: {pool.participant_ids.length} / {pool.capacity}
</p> </p>
<p className="text-left">Start Time: {pool.start_time}</p> <p className="text-left">Start Time: {pool.start_time}</p>
<p className="text-left">End Time: {pool.end_time}</p> <p className="text-left">End Time: {pool.end_time}</p>

View File

@ -1,12 +1,14 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
const Profile = (props) => { const Profile = () => {
const [state, setState] = useState({ const [state, setState] = useState({
user: { username: 'HyperionLegion' }, user: {
username: 'HyperionLegion',
},
pools: [ pools: [
{ {
pool_title: 'TJ Carpool', title: 'TJ Carpool',
pool_text: 'Carpool from TJ track to homes', description: 'Carpool from TJ track to homes',
start_time: '4/10/2021 3:00 PM', start_time: '4/10/2021 3:00 PM',
id: 1, id: 1,
end_time: '4/10/2021 4:00 PM', end_time: '4/10/2021 4:00 PM',
@ -17,8 +19,8 @@ const Profile = (props) => {
], ],
}, },
{ {
pool_title: 'TJ Carpool', title: 'TJ Carpool',
pool_text: 'Carpool from TJ track to homes', description: 'Carpool from TJ track to homes',
start_time: '4/10/2021 3:00 PM', start_time: '4/10/2021 3:00 PM',
id: 2, id: 2,
end_time: '4/10/2021 4:00 PM', end_time: '4/10/2021 4:00 PM',
@ -29,8 +31,8 @@ const Profile = (props) => {
], ],
}, },
{ {
pool_title: 'TJ Carpool', title: 'TJ Carpool',
pool_text: 'Carpool from TJ track to homes', description: 'Carpool from TJ track to homes',
start_time: '4/10/2021 3:00 PM', start_time: '4/10/2021 3:00 PM',
id: 3, id: 3,
end_time: '4/10/2021 4:00 PM', end_time: '4/10/2021 4:00 PM',
@ -75,7 +77,7 @@ const Profile = (props) => {
className="text-left m-2 p-1" className="text-left m-2 p-1"
style={{ backgroundColor: '#D6D1D0' }} style={{ backgroundColor: '#D6D1D0' }}
> >
<a href={'pool/' + pool.id}>{pool.pool_title}</a> <a href={'pool/' + pool.id}>{pool.title}</a>
</div> </div>
); );
})} })}

View File

@ -1,7 +1,13 @@
import React, { useState, useEffect, useCallback } from 'react'; import React, {
useState,
useEffect,
useCallback,
FormEventHandler,
} from 'react';
import { useParams } from 'react-router-dom';
const UpdatePool = (props) => { const UpdatePool = () => {
const id = props.match.params.id; const id = useParams<{ id: string }>().id;
// eslint-disable-next-line // eslint-disable-next-line
const [pool, setPool] = useState({ const [pool, setPool] = useState({
@ -24,7 +30,7 @@ const UpdatePool = (props) => {
} }
}); });
}, [id]); }, [id]);
const onSubmit = (e) => { const onSubmit: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault(); e.preventDefault();
fetch(`${process.env.REACT_APP_API_ENDPOINT}/create_pool`) fetch(`${process.env.REACT_APP_API_ENDPOINT}/create_pool`)
.then((response) => response.json()) .then((response) => response.json())
@ -49,7 +55,7 @@ const UpdatePool = (props) => {
<h1 className="form-title" style={{ fontFamily: 'Impact' }}> <h1 className="form-title" style={{ fontFamily: 'Impact' }}>
Update Pool Update Pool
</h1> </h1>
<label className="" for="title"> <label className="" htmlFor="title">
Pool Title:{' '} Pool Title:{' '}
</label> </label>
<input <input
@ -61,7 +67,7 @@ const UpdatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="capacity"> <label className="" htmlFor="capacity">
Pool Capacity: Pool Capacity:
</label> </label>
<input <input
@ -73,7 +79,7 @@ const UpdatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="pool_start"> <label className="" htmlFor="pool_start">
Start Time: Start Time:
</label> </label>
<input <input
@ -85,7 +91,7 @@ const UpdatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="pool_end"> <label className="" htmlFor="pool_end">
End Time: End Time:
</label> </label>
<input <input
@ -97,11 +103,10 @@ const UpdatePool = (props) => {
></input> ></input>
</div> </div>
<div className="form-group"> <div className="form-group">
<label className="" for="title"> <label className="" htmlFor="title">
Pool Description: Pool Description:
</label> </label>
<textarea <textarea
type="text"
id="Pool-text" id="Pool-text"
name="Pool-text" name="Pool-text"
style={{ height: '200px' }} style={{ height: '200px' }}

1
src/react-app-env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="react-scripts" />

41
src/types.d.ts vendored Normal file
View File

@ -0,0 +1,41 @@
declare namespace Carpool {
export interface Group {
id: string;
member_ids: string[];
}
export interface User {
id: string;
email: string;
username: string;
first_name: string;
last_name: string;
}
export interface Comment {
id: string;
body: string;
author_id: string;
}
export type Status = 'pending' | 'cancelled' | 'completed' | 'interrupted';
export interface Pool {
id: string;
title: string;
description: string;
participant_ids: string[];
driver_id: string;
create_time: string;
update_time: string;
comments: Comment[];
group_id: string;
status: Status;
capacity: number;
direction: 'pickup' | 'dropoff';
author_id: string;
type: 'request' | 'offer';
start_time: string;
end_time: string;
}
}

21
tsconfig.json Normal file
View File

@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"files": ["src/types.d.ts"]
}