fix all type errors

This commit is contained in:
Thomas Ruoff
2021-02-15 23:29:25 +01:00
parent 85a7b54a13
commit 3386fb3928
14 changed files with 123 additions and 132 deletions

View File

@@ -1,96 +1,83 @@
import React, { Component } from 'react'
import React, { useState, useEffect } from 'react'
import LetterOptions from './LetterOptions'
import Button from './Button'
import Preview from './Preview'
import LatestList from './LatestList'
import { generatePdf, getLatest, removeLatest } from './apiHelper'
import { ILatest } from '../interfaces/ILatest'
import { IDocProps } from '../interfaces/IDocProps'
//import './App.css';
class App extends Component {
componentDidMount() {
this._getLatest()
}
render() {
const state: Record<string, unknown> = this.state || {}
return (
<div className="home">
<div>
<LetterOptions onChange={this._onChange.bind(this)} {...state.options} />
<LatestList
latest={state.latest}
onSelect={this._onSelectLatest.bind(this)}
onRemove={this._onRemoveLatest.bind(this)}
/>
</div>
<div>
<div>
<Button onClick={this._onGenerate.bind(this)}>Backe PDF</Button>
<Button onClick={this._onClear.bind(this)}>Alles Löschen</Button>
</div>
<Preview pdfUrl={state.pdfUrl} pdfIsLoading={state.pdfIsLoading} pdfError={state.pdfError} />
</div>
</div>
)
}
_onSelectLatest(selectedOptions) {
this.setState({ options: Object.assign({}, selectedOptions) })
}
_onRemoveLatest(item) {
removeLatest(item).then(() => {
const latest = this.state.latest.filter((curr) => curr.id !== item.id)
this.setState({ latest })
export default function App() {
const [options, setOptions] = useState<IDocProps>({
template: 'brief-fam',
subject: '',
body: '',
address: '',
})
}
const [latest, setLatest] = useState<ILatest[]>([])
const [pdfUrl, setPdfUrl] = useState<string | null>(null)
const [pdfIsLoading, setPdfIsLoading] = useState<boolean>(false)
const [pdfError, setPdfError] = useState<string | null>(null)
_onClear() {
window.location.reload()
}
_onGenerate() {
const state = this.state || {}
this.setState({
pdfIsLoading: true,
pdfError: null,
})
generatePdf(state.options)
.then((data) => {
const { id } = data
this.setState({
pdfIsLoading: false,
pdfUrl: `/api/pdf/${id}`,
})
})
.catch((error) => {
this.setState({
pdfIsLoading: false,
pdfError: error.message,
pdfUrl: null,
})
})
.then(() => this._getLatest())
}
_getLatest() {
useEffect(() => {
getLatest()
.then((latest) => this.setState({ latest }))
.then((latest) => setLatest(latest))
.catch((err) => console.error('Unable to get latest:', err))
}
}, [pdfUrl])
_onChange(name, event) {
const _onChange = (name: string, event: React.ChangeEvent<{ value: string }>) => {
if (!name) {
return
}
const value = event && event.target && event.target.value
const options = Object.assign({}, this.state.options, { [name]: value || undefined })
this.setState({ options })
setOptions({ ...options, [name]: value || undefined })
}
}
export default App
const _onSelectLatest = (selectedOption: ILatest) => {
setOptions({ ...selectedOption })
}
const _onRemoveLatest = (item: ILatest) => {
removeLatest(item).then(() => setLatest(latest.filter((curr) => curr.id !== item.id)))
}
const _onClear = () => {
window.location.reload()
}
const _onGenerate = () => {
setPdfIsLoading(true)
setPdfError(null)
generatePdf(options)
.then((data) => {
const { id } = data
setPdfIsLoading(false)
setPdfUrl(`/api/pdf/${id}`)
})
.catch((error) => {
setPdfIsLoading(false)
setPdfError(error.message)
setPdfUrl(null)
})
}
return (
<div className="home">
<div>
<LetterOptions onChange={_onChange} {...options} />
<LatestList latest={latest} onSelect={_onSelectLatest} onRemove={_onRemoveLatest} />
</div>
<div>
<div>
<Button onClick={_onGenerate}>Backe PDF</Button>
<Button onClick={_onClear}>Alles Löschen</Button>
</div>
<Preview pdfUrl={pdfUrl} pdfIsLoading={pdfIsLoading} pdfError={pdfError} />
</div>
</div>
)
}

View File

@@ -3,15 +3,15 @@ import React from 'react'
export default function Input({
text,
name,
value,
value = '',
placeholder,
onchange,
}: {
text: string
name: string
value: string
placeholder: string
onchange: () => void
value?: string
placeholder?: string
onchange: (name: string, event: React.ChangeEvent<HTMLInputElement>) => void
}) {
return (
<label>

View File

@@ -11,7 +11,7 @@ import { IDocProps } from '../interfaces/IDocProps'
const EXAMPLE_ADDRESS = 'Max Mustermann\nMusterstr. 73\n12345 Musterstadt'
interface IProps extends IDocProps {
onChange: () => void
onChange: (name: string, event: React.ChangeEvent<{ value: string }>) => void
}
export default function LetterOptions(props: IProps) {

View File

@@ -1,14 +1,7 @@
import React from 'react'
import { IPdfProps } from '../interfaces/IPdfProps'
export default function Preview({
pdfIsLoading,
pdfError,
pdfUrl,
}: {
pdfIsLoading: boolean
pdfError: string
pdfUrl: string
}) {
export default function Preview({ pdfIsLoading, pdfError, pdfUrl }: IPdfProps) {
if (pdfIsLoading) {
return <div>Lade&hellip;</div>
}

View File

@@ -10,7 +10,7 @@ export default function Select({
name: string
text: string
value: string
onchange: () => void
onchange: (name: string, event: React.ChangeEvent<{ value: string }>) => void
options: { name: string; value: string }[]
}) {
return (

View File

@@ -10,7 +10,7 @@ export default function TextAreaInput({
text: string
name: string
placeholder: string
onchange: () => void
onchange: (name: string, event: React.ChangeEvent<HTMLTextAreaElement>) => void
value: string
}) {
return (

View File

@@ -1,3 +1,4 @@
import { IDocProps } from '../interfaces/IDocProps'
import { ILatest } from '../interfaces/ILatest'
function checkStatus(res: Response) {
@@ -6,7 +7,7 @@ function checkStatus(res: Response) {
}
}
export async function generatePdf(state: Record<string, string>) {
export async function generatePdf(state: IDocProps) {
const options = {
method: 'POST',
headers: {

5
interfaces/IPdfProps.ts Normal file
View File

@@ -0,0 +1,5 @@
export interface IPdfProps {
pdfUrl: string | null
pdfIsLoading: boolean
pdfError: string | null
}

View File

@@ -2,6 +2,7 @@ const storeDir = process.env.JSON_STORE || '/tmp/pdfer-store/'
import { promisify } from 'util'
// @ts-ignore
import JsonStore from 'json-fs-store'
const store = JsonStore(storeDir)

View File

@@ -1,8 +1,10 @@
import { IDocProps } from '../interfaces/IDocProps'
function convertLineBreaks(lines: string) {
return lines.replace(/\n/g, '\\\\')
}
export function brief(options: Record<string, string>) {
export function brief(options: IDocProps) {
const {
template = 'brief-fam',
subject = '',
@@ -21,7 +23,7 @@ export function brief(options: Record<string, string>) {
closing = 'Mit freundlichen Grüßen',
ps = '',
enclosing = '',
} = options
} = { ...options }
return `% brief document
\\documentclass{scrlttr2}

View File

@@ -1,11 +1,11 @@
import {promises} from 'fs'
import { promises } from 'fs'
import { NextApiRequest, NextApiResponse } from 'next'
import {remove as storeRemove} from '../../../lib/store'
import { remove as storeRemove } from '../../../lib/store'
import { getPdfPath } from '../../../lib/utils'
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const { method } = req;
const { method } = req
switch (req.method) {
case 'GET':
@@ -14,14 +14,16 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
query: { id: idArg },
} = req
const fileContent = await promises.readFile(getPdfPath(idArg))
const id = Array.isArray(idArg) ? idArg[0] : idArg
const fileContent = await promises.readFile(getPdfPath(id))
res.setHeader('Content-Type', 'application/pdf')
res.status(200).send(fileContent);
res.status(200).send(fileContent)
} catch (error) {
console.error(error)
res.status(404).json({ statusCode: 404, message: 'Method Not Allowed' })
}
break;
break
case 'DELETE':
try {
const {
@@ -35,11 +37,11 @@ const handler = async (req: NextApiRequest, res: NextApiResponse) => {
console.error(error)
res.status(404).json({ statusCode: 404, message: 'Method Not Allowed' })
}
break;
break
default:
res.setHeader('Allow', ['GET', 'DELETE'])
res.status(405).end(`Method ${method} Not Allowed`)
}
}
export default handler;
export default handler

View File

@@ -2,7 +2,7 @@ import Layout from '../components/Layout'
import App from '../components/App'
const IndexPage = () => (
<Layout title="Home | Next.js + TypeScript Example">
<Layout>
<App />
</Layout>
)