1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
| import React, { useEffect, useState } from 'react';
| import { toDataURL } from 'qrcode';
| import { Box, Skeleton, Typography, useTheme } from '@mui/material';
|
| const CodeQr = ({ value, size = 160, loading }) => {
| const [dataUrl, setDataUrl] = useState(null);
| const theme = useTheme();
|
| useEffect(() => {
| let ignore = false;
| if (!value) {
| setDataUrl(null);
| return () => { ignore = true; };
| }
| const darkColor = theme.palette.mode === 'dark' ? '#f5f6fa' : '#111111';
| const lightColor = theme.palette.mode === 'dark' ? '#1b1b1b' : '#fafafa';
| toDataURL(String(value), {
| width: size,
| margin: 2,
| color: {
| dark: darkColor,
| light: lightColor
| },
| }).then((url) => {
| if (!ignore) {
| setDataUrl(url);
| }
| }).catch((error) => {
| console.error('QR render failed', error);
| if (!ignore) {
| setDataUrl(null);
| }
| });
| return () => {
| ignore = true;
| };
| }, [value, size, theme.palette.mode]);
|
| if (loading) {
| return <Skeleton variant="rectangular" height={size} width={size} sx={{ borderRadius: 2 }} />;
| }
|
| if (!value || !dataUrl) {
| return (
| <Typography variant="body2" color="text.disabled">
| -
| </Typography>
| );
| }
|
| return (
| <Box
| component="img"
| src={dataUrl}
| alt="Code QR"
| sx={{
| width: size,
| height: size,
| borderRadius: 2,
| boxShadow: (theme) => theme.shadows[3],
| p: 1,
| backgroundColor: 'background.paper'
| }}
| />
| );
| };
|
| export default CodeQr;
|
|