mirror of
https://github.com/tomru/pdfer.git
synced 2026-03-02 22:17:18 +01:00
work on styles
This commit is contained in:
@@ -11,7 +11,7 @@ import { IDocProps } from '../interfaces/IDocProps'
|
||||
|
||||
export default function App() {
|
||||
const [options, setOptions] = useState<IDocProps>({
|
||||
address: 'Max Mustermann\\\\Musterstrasse\\\\12345 Musterstadt',
|
||||
address: 'Max Mustermann\nMusterstrasse\n12345 Musterstadt',
|
||||
body: 'Inhalt des Briefs',
|
||||
closing: 'Mit freundlichen Grüßen',
|
||||
customer: '',
|
||||
@@ -79,17 +79,17 @@ export default function App() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="home">
|
||||
<div>
|
||||
<div className="flex flex-col space-x-5 max-w-7xl mx-auto py-3 sm:px-2 lg:px-3 bg-gray-100">
|
||||
<div className="flex flex-col space-y-5 shadow sm:rounded-md sm:overflow-hidden">
|
||||
<LetterOptions onChange={_onChange} {...options} />
|
||||
<LatestList latest={latest} onSelect={_onSelectLatest} onRemove={_onRemoveLatest} />
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<div className="flex space-x-3">
|
||||
<Button onClick={_onGenerate}>Backe PDF</Button>
|
||||
<Button onClick={_onClear}>Alles Löschen</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col space-y-5">
|
||||
<Preview pdfUrl={pdfUrl} pdfIsLoading={pdfIsLoading} pdfError={pdfError} />
|
||||
<LatestList latest={latest} onSelect={_onSelectLatest} onRemove={_onRemoveLatest} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -2,7 +2,11 @@ import React from 'react'
|
||||
|
||||
export default function Button({ children, onClick }: { children: React.ReactNode; onClick: () => void }) {
|
||||
return (
|
||||
<button className="p-button" onClick={onClick}>
|
||||
<button
|
||||
type="button"
|
||||
onClick={onClick}
|
||||
className="inline-flex items-center px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
|
||||
@@ -2,8 +2,8 @@ import React from 'react'
|
||||
|
||||
export default function Header() {
|
||||
return (
|
||||
<header className="header">
|
||||
<h1>PDFer</h1>
|
||||
<header className="my-3">
|
||||
<h1 className="text-3xl font-extrabold text-gray-900 tracking-tight">PDFer</h1>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,15 +14,20 @@ export default function Input({
|
||||
onchange: (name: string, event: ChangeEvent<{ value: string }>) => void
|
||||
}) {
|
||||
return (
|
||||
<label>
|
||||
<div>
|
||||
<label htmlFor={name} className="block text-sm font-medium text-gray-700">
|
||||
{text}
|
||||
<input
|
||||
className={name}
|
||||
type="text"
|
||||
placeholder={placeholder}
|
||||
onChange={onchange.bind(null, name)}
|
||||
value={value}
|
||||
/>
|
||||
</label>
|
||||
<div className="mt-1 flex rounded-md shadow-sm">
|
||||
<input
|
||||
type="text"
|
||||
name={name}
|
||||
className="focus:ring-indigo-500 focus:border-indigo-500 flex-1 block w-full rounded-none rounded-r-md sm:text-sm border-gray-300"
|
||||
placeholder={placeholder}
|
||||
value={value}
|
||||
onChange={onchange.bind(null, name)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ import Header from './Header'
|
||||
|
||||
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<div id="app">
|
||||
<div>
|
||||
<Header />
|
||||
<div id="content">{children}</div>
|
||||
<main>{children}</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ export default function LetterOptions(props: IProps) {
|
||||
]
|
||||
|
||||
return (
|
||||
<div className="letter-options">
|
||||
<div className="px-4 py-5 bg-white space-y-6 sm:p-6">
|
||||
<Select
|
||||
name="template"
|
||||
text="Vorlage"
|
||||
@@ -50,8 +50,16 @@ export default function LetterOptions(props: IProps) {
|
||||
placeholder={EXAMPLE_ADDRESS}
|
||||
onchange={props.onChange}
|
||||
value={props.address}
|
||||
styles="h-20"
|
||||
/>
|
||||
<Input name="subject" text="Betreff" placeholder="Betreffzeile" onchange={props.onChange} value={props.subject} />
|
||||
<TextAreaInput
|
||||
name="body"
|
||||
text="Brieftext"
|
||||
onchange={props.onChange}
|
||||
placeholder="Inhalt des Briefes"
|
||||
value={props.body}
|
||||
/>
|
||||
<Collapsible trigger="Bezugszeichenzeile">
|
||||
<Input name="yourRef" text="Ihr Zeichen" onchange={props.onChange} value={props.yourRef} />
|
||||
<Input name="yourMail" text="Ihr Schreiben vom" onchange={props.onChange} value={props.yourMail} />
|
||||
@@ -77,13 +85,6 @@ export default function LetterOptions(props: IProps) {
|
||||
/>
|
||||
<Input name="specialMail" text="Versandhinweis" onchange={props.onChange} value={props.specialMail} />
|
||||
</Collapsible>
|
||||
<TextAreaInput
|
||||
name="body"
|
||||
text="Brieftext"
|
||||
onchange={props.onChange}
|
||||
placeholder="Inhalt des Briefes"
|
||||
value={props.body}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -14,15 +14,22 @@ export default function Select({
|
||||
options: { name: string; value: string }[]
|
||||
}) {
|
||||
return (
|
||||
<label>
|
||||
<div className="">
|
||||
<label htmlFor={name} className="block text-sm font-medium text-gray-700">
|
||||
{text}
|
||||
<select className={name} onChange={onchange.bind(null, name)} value={value}>
|
||||
</label>
|
||||
<select
|
||||
name={name}
|
||||
className="mt-1 block w-full py-2 px-3 border border-gray-300 bg-white rounded-md shadow-sm focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
|
||||
onChange={onchange.bind(null, name)}
|
||||
value={value}
|
||||
>
|
||||
{options.map((option) => (
|
||||
<option value={option.value} key={option.value}>
|
||||
{option.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,17 +6,31 @@ export default function TextAreaInput({
|
||||
placeholder,
|
||||
onchange,
|
||||
value,
|
||||
styles = '',
|
||||
}: {
|
||||
text: string
|
||||
name: string
|
||||
placeholder: string
|
||||
onchange: (name: string, event: ChangeEvent<{ value: string }>) => void
|
||||
value: string
|
||||
styles?: string
|
||||
}) {
|
||||
return (
|
||||
<label>
|
||||
<div>
|
||||
<label htmlFor={name} className="block text-sm font-medium text-gray-700">
|
||||
{text}
|
||||
<textarea className={name} placeholder={placeholder} onChange={onchange.bind(null, name)} value={value} />
|
||||
</label>
|
||||
<div className="mt-1">
|
||||
<textarea
|
||||
id="about"
|
||||
name="about"
|
||||
rows={10}
|
||||
className={`shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border-gray-300 rounded-md ${styles}`}
|
||||
placeholder={placeholder}
|
||||
onChange={onchange.bind(null, name)}
|
||||
value={value}
|
||||
></textarea>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
13
package-lock.json
generated
13
package-lock.json
generated
@@ -307,6 +307,14 @@
|
||||
"resolved": "https://registry.npmjs.org/@opentelemetry/context-base/-/context-base-0.14.0.tgz",
|
||||
"integrity": "sha512-sDOAZcYwynHFTbLo6n8kIbLiVF3a3BLkrmehJUyEbT9F+Smbi47kLGS2gG2g0fjBLR/Lr1InPD7kXL7FaTqEkw=="
|
||||
},
|
||||
"@tailwindcss/forms": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.2.1.tgz",
|
||||
"integrity": "sha512-czfvEdY+J2Ogfd6RUSr/ZSUmDxTujr34M++YLnp2cCPC3oJ4kFvFMaRXA6cEXKw7F1hJuapdjXRjsXIEXGgORg==",
|
||||
"requires": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
}
|
||||
},
|
||||
"@types/istanbul-lib-coverage": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
|
||||
@@ -1800,6 +1808,11 @@
|
||||
"integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==",
|
||||
"optional": true
|
||||
},
|
||||
"mini-svg-data-uri": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/mini-svg-data-uri/-/mini-svg-data-uri-1.2.3.tgz",
|
||||
"integrity": "sha512-zd6KCAyXgmq6FV1mR10oKXYtvmA9vRoB6xPSTUJTbFApCtkefDnYueVR1gkof3KcdLZo1Y8mjF2DFmQMIxsHNQ=="
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"format": "prettier --write **/*.{ts,tsx,json}"
|
||||
},
|
||||
"dependencies": {
|
||||
"@tailwindcss/forms": "^0.2.1",
|
||||
"@types/jest": "^26.0.20",
|
||||
"autoprefixer": "^10.2.4",
|
||||
"json-fs-store": "^1.0.1",
|
||||
|
||||
@@ -1,24 +1,9 @@
|
||||
// import App from "next/app";
|
||||
import type { AppProps /*, AppContext */ } from 'next/app'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
import '../styles/index.css'
|
||||
import '../styles/App.css'
|
||||
import '../styles/LetterOptions.css'
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
// Only uncomment this method if you have blocking data requirements for
|
||||
// every single page in your application. This disables the ability to
|
||||
// perform automatic static optimization, causing every page in your app to
|
||||
// be server-side rendered.
|
||||
//
|
||||
// MyApp.getInitialProps = async (appContext: AppContext) => {
|
||||
// // calls page's `getInitialProps` and fills `appProps.pageProps`
|
||||
// const appProps = await App.getInitialProps(appContext);
|
||||
|
||||
// return { ...appProps }
|
||||
// }
|
||||
|
||||
export default MyApp
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
header h1 {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
.p-button {
|
||||
margin-top: 12px;
|
||||
margin-right: 12px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.home {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.home > div {
|
||||
padding: 12px;
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
.letter-options {
|
||||
width: 320px;
|
||||
}
|
||||
|
||||
.letter-options label {
|
||||
display: block;
|
||||
color: #333;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
.letter-options input,
|
||||
.letter-options textarea,
|
||||
.letter-options select {
|
||||
margin-top: 3px;
|
||||
margin-bottom: 12px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.letter-options textarea {
|
||||
resize: vertical;
|
||||
}
|
||||
|
||||
.letter-options textarea.address {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.letter-options textarea.body {
|
||||
height: 340px;
|
||||
}
|
||||
|
||||
.letter-options .Collapsible {
|
||||
background-color: #ddd;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.letter-options .Collapsible__trigger {
|
||||
padding-left: 6px;
|
||||
cursor: pointer;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.letter-options .Collapsible__trigger.is-closed:before {
|
||||
content: "> ";
|
||||
}
|
||||
|
||||
.letter-options .Collapsible__trigger.is-open:before {
|
||||
content: "< ";
|
||||
}
|
||||
|
||||
.letter-options .Collapsible {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.letter-options .Collapsible__contentInner {
|
||||
background-color: #fff;
|
||||
padding-top: 12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
@@ -1,3 +1,34 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
.Collapsible {
|
||||
background-color: #ddd;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.Collapsible__trigger {
|
||||
padding-left: 6px;
|
||||
cursor: pointer;
|
||||
line-height: 24px;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Collapsible__trigger.is-closed:before {
|
||||
content: '> ';
|
||||
}
|
||||
|
||||
.Collapsible__trigger.is-open:before {
|
||||
content: '< ';
|
||||
}
|
||||
|
||||
.Collapsible {
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.Collapsible__contentInner {
|
||||
background-color: #fff;
|
||||
padding-top: 12px;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@ module.exports = {
|
||||
variants: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [require('@tailwindcss/forms')],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user