mirror of
https://github.com/shlinkio/shlink-web-client.git
synced 2026-03-18 21:43:49 +00:00
Extract shlink-web-component outside of src folder
This commit is contained in:
95
shlink-web-component/short-urls/helpers/QrCodeModal.tsx
Normal file
95
shlink-web-component/short-urls/helpers/QrCodeModal.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { faFileDownload as downloadIcon } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
import { useMemo, useState } from 'react';
|
||||
import { ExternalLink } from 'react-external-link';
|
||||
import { Button, FormGroup, Modal, ModalBody, ModalHeader, Row } from 'reactstrap';
|
||||
import type { ImageDownloader } from '../../../src/common/services/ImageDownloader';
|
||||
import { CopyToClipboardIcon } from '../../../src/utils/CopyToClipboardIcon';
|
||||
import type { QrCodeFormat, QrErrorCorrection } from '../../../src/utils/helpers/qrCodes';
|
||||
import { buildQrCodeUrl } from '../../../src/utils/helpers/qrCodes';
|
||||
import type { ShortUrlModalProps } from '../data';
|
||||
import { QrErrorCorrectionDropdown } from './qr-codes/QrErrorCorrectionDropdown';
|
||||
import { QrFormatDropdown } from './qr-codes/QrFormatDropdown';
|
||||
import './QrCodeModal.scss';
|
||||
|
||||
export const QrCodeModal = (imageDownloader: ImageDownloader) => (
|
||||
{ shortUrl: { shortUrl, shortCode }, toggle, isOpen }: ShortUrlModalProps,
|
||||
) => {
|
||||
const [size, setSize] = useState(300);
|
||||
const [margin, setMargin] = useState(0);
|
||||
const [format, setFormat] = useState<QrCodeFormat>('png');
|
||||
const [errorCorrection, setErrorCorrection] = useState<QrErrorCorrection>('L');
|
||||
const qrCodeUrl = useMemo(
|
||||
() => buildQrCodeUrl(shortUrl, { size, format, margin, errorCorrection }),
|
||||
[shortUrl, size, format, margin, errorCorrection],
|
||||
);
|
||||
const totalSize = useMemo(() => size + margin, [size, margin]);
|
||||
const modalSize = useMemo(() => {
|
||||
if (totalSize < 500) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return totalSize < 800 ? 'lg' : 'xl';
|
||||
}, [totalSize]);
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} toggle={toggle} centered size={modalSize}>
|
||||
<ModalHeader toggle={toggle}>
|
||||
QR code for <ExternalLink href={shortUrl}>{shortUrl}</ExternalLink>
|
||||
</ModalHeader>
|
||||
<ModalBody>
|
||||
<Row>
|
||||
<FormGroup className="d-grid col-md-6">
|
||||
<label>Size: {size}px</label>
|
||||
<input
|
||||
type="range"
|
||||
className="form-control-range"
|
||||
value={size}
|
||||
step={10}
|
||||
min={50}
|
||||
max={1000}
|
||||
onChange={(e) => setSize(Number(e.target.value))}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup className="d-grid col-md-6">
|
||||
<label htmlFor="marginControl">Margin: {margin}px</label>
|
||||
<input
|
||||
id="marginControl"
|
||||
type="range"
|
||||
className="form-control-range"
|
||||
value={margin}
|
||||
step={1}
|
||||
min={0}
|
||||
max={100}
|
||||
onChange={(e) => setMargin(Number(e.target.value))}
|
||||
/>
|
||||
</FormGroup>
|
||||
<FormGroup className="d-grid col-md-6">
|
||||
<QrFormatDropdown format={format} setFormat={setFormat} />
|
||||
</FormGroup>
|
||||
<FormGroup className="col-md-6">
|
||||
<QrErrorCorrectionDropdown errorCorrection={errorCorrection} setErrorCorrection={setErrorCorrection} />
|
||||
</FormGroup>
|
||||
</Row>
|
||||
<div className="text-center">
|
||||
<div className="mb-3">
|
||||
<ExternalLink href={qrCodeUrl} />
|
||||
<CopyToClipboardIcon text={qrCodeUrl} />
|
||||
</div>
|
||||
<img src={qrCodeUrl} className="qr-code-modal__img" alt="QR code" />
|
||||
<div className="mt-3">
|
||||
<Button
|
||||
block
|
||||
color="primary"
|
||||
onClick={() => {
|
||||
imageDownloader.saveImage(qrCodeUrl, `${shortCode}-qr-code.${format}`).catch(() => {});
|
||||
}}
|
||||
>
|
||||
Download <FontAwesomeIcon icon={downloadIcon} className="ms-1" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</ModalBody>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user