diff --git a/package.json b/package.json index f179c7d..4654aec 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ }, "dependencies": { "@react-pdf/renderer": "^3.4.2", - "@uidotdev/usehooks": "^2.4.1", "@vitejs/plugin-react-swc": "^3.6.0", "date-fns": "^3.6.0", "file-saver": "^2.0.5", diff --git a/src/App.tsx b/src/App.tsx index 0688919..58b35be 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -17,7 +17,7 @@ function App() { return (
-

React Invoice Generator

+

React Invoice Generator

) diff --git a/src/components/DownloadPDF.tsx b/src/components/DownloadPDF.tsx index 5f3dbd0..a05c30b 100644 --- a/src/components/DownloadPDF.tsx +++ b/src/components/DownloadPDF.tsx @@ -1,7 +1,6 @@ -import React, { FC } from 'react' +import { ChangeEvent, FC, useEffect, useState } from 'react' import { PDFDownloadLink } from '@react-pdf/renderer' import { Invoice, TInvoice } from '../data/types' -import { useDebounce } from '@uidotdev/usehooks' import InvoicePage from './InvoicePage' import FileSaver from 'file-saver' @@ -11,9 +10,20 @@ interface Props { } const Download: FC = ({ data, setData }) => { - const debounced = useDebounce(data, 500) + const [showDoc, setShowDoc] = useState(true) + const [t, setT] = useState(null) - function handleInput(e: React.ChangeEvent) { + useEffect(() => { + setShowDoc(false) + if (t) clearTimeout(t) + setT( + setTimeout(() => { + setShowDoc(true) + }, 500) as any, + ) + }, [data]) + + function handleInput(e: ChangeEvent) { if (!e.target.files?.length) return const file = e.target.files[0] @@ -37,7 +47,7 @@ const Download: FC = ({ data, setData }) => { } function handleSaveTemplate() { - const blob = new Blob([JSON.stringify(debounced)], { + const blob = new Blob([JSON.stringify(data)], { type: 'text/plain;charset=utf-8', }) FileSaver(blob, title + '.template') @@ -45,29 +55,32 @@ const Download: FC = ({ data, setData }) => { const title = data.invoiceTitle ? data.invoiceTitle.toLowerCase() : 'invoice' return ( -
- } - fileName={`${title}.pdf`} - aria-label="Save PDF" - title="Save PDF" - className="download-pdf__pdf" - > -

Save PDF

- +
+ {showDoc ? ( + } + fileName={`${title}.pdf`} + aria-label="Save PDF" + title="Save PDF" + className="download-pdf__pdf" + > + ) : ( +
) } diff --git a/src/images/template_download.svg b/src/images/template_download.svg index f747796..1a19017 100644 --- a/src/images/template_download.svg +++ b/src/images/template_download.svg @@ -5,12 +5,12 @@ viewBox="0 0 58 58" style="enable-background:new 0 0 58 58;" xml:space="preserve"> - + - + - + diff --git a/src/scss/_app.scss b/src/scss/_app.scss index 96ab153..5a82b8c 100644 --- a/src/scss/_app.scss +++ b/src/scss/_app.scss @@ -1,6 +1,16 @@ .app { - margin: 30px auto 50px auto; + margin: 30px auto 50px; width: 700px; + + &__title { + display: inline-block; + width: 100%; + text-align: center; + @media only screen and (max-width: 920px) { + margin-left: 4px; + text-align: start; + } + } } .input, @@ -43,47 +53,75 @@ } .download-pdf { - position: fixed; - top: 100px; - margin-left: -110px; - width: 40px; - height: 40px; + overflow: hidden; + position: absolute; + top: 2px; + left: -82px; transition: opacity 0.2s ease-in-out; - - &.loading { - opacity: 0.3; + display: grid; + justify-items: center; + align-items: center; + gap: 4px 0; + grid-template-columns: 60px; + text-align: center; + + @media only screen and (max-width: 920px) { + top: -82px; + right: 4px; + left: auto; + grid-template-rows: 40px 20px; + grid-auto-flow: column; + gap: 0 10px; } button { border: none; } + > .loading { + opacity: 0.3; + cursor: wait !important; + } - a, - label, - button { + .download-pdf__pdf, + .download-pdf__template_download, + .download-pdf__template_upload { display: block; background-repeat: no-repeat; - top: 0; - left: 0; - width: 100%; - height: 100%; + background-position: center; + width: 30px; + height: 30px; + cursor: pointer; + border-radius: 5px; + outline: #fff solid 2px; + &:hover { + outline-offset: 2px; + ~ p { + opacity: 1; + } + } + + @media only screen and (min-width: 921px) { + margin-top: 12px; + } + } + button { + background-color: transparent; } .download-pdf__pdf { - background: url('../images/download.svg'); + background-image: url('../images/download.svg'); } .download-pdf__template_download { - width: 30px; - height: 30px; - background: url('../images/template_download.svg'); + background-image: url('../images/template_download.svg'); } .download-pdf__template_upload { - width: 30px; - height: 30px; - background: url('../images/template_upload.svg'); + background-image: url('../images/template_upload.svg'); } input[type='file'] { visibility: hidden; } + p { + margin: 0; + } } .image { diff --git a/yarn.lock b/yarn.lock index 7cce5a5..7714129 100644 --- a/yarn.lock +++ b/yarn.lock @@ -525,11 +525,6 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@uidotdev/usehooks@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf" - integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg== - "@vitejs/plugin-react-swc@^3.6.0": version "3.6.0" resolved "https://registry.yarnpkg.com/@vitejs/plugin-react-swc/-/plugin-react-swc-3.6.0.tgz#dc9cd1363baf3780f3ad3e0a12a46a3ffe0c7526"