11import { useMutation , useQuery } from "@apollo/client/react" ;
2- import { Button , Stack , TextField , Typography } from "@mui/material" ;
2+ import { Button , Link , Stack , TextField , Typography } from "@mui/material" ;
33import { GET_EQUIPMENT_BY_ID } from "../../../queries/equipmentQueries" ;
44import { useNavigate , useParams } from "react-router-dom" ;
55import RequestWrapper2 from "../../../common/RequestWrapper2" ;
66import EquipmentInformation from "./EquipmentInformation" ;
77import PrettyModal from "../../../common/PrettyModal" ;
88import InstanceGrid from "./InstanceGrid" ;
99import { useIsMobile } from "../../../common/IsMobileProvider" ;
10- import { useState } from "react" ;
10+ import { useRef , useState } from "react" ;
1111import AddIcon from '@mui/icons-material/Add' ;
1212import { CREATE_EQUIPMENT_INSTANCE } from "../../../queries/equipmentInstanceQueries" ;
1313import HistoryIcon from '@mui/icons-material/History' ;
@@ -18,6 +18,8 @@ import MaintenanceTicketGrid from "../maintenance_pages/MaintenanceTicketGrid";
1818import WarningIcon from '@mui/icons-material/Warning' ;
1919import NewTicketModal from "../maintenance_pages/NewTicketModal" ;
2020import { useMakeTheme } from "../../../common/MakeThemeProvider" ;
21+ import QrCodeIcon from '@mui/icons-material/QrCode' ;
22+ import { QRCode } from "react-qr-code" ;
2123
2224export interface Equipment {
2325 id : number ;
@@ -51,13 +53,57 @@ export interface Equipment {
5153
5254}
5355
56+
57+
58+
59+
5460export default function ManageEquipmentPage ( ) {
5561 const { makerspaceID, equipmentID } = useParams < { makerspaceID : string , equipmentID : string } > ( ) ;
5662 const isMobile = useIsMobile ( ) ;
5763 const navigate = useNavigate ( ) ;
5864 const user = useCurrentUser ( ) ;
5965 const makeTheme = useMakeTheme ( ) ;
6066
67+ const qrRef = useRef ( null ) ;
68+
69+ function copyQRCode ( ) {
70+ try {
71+ const svg = qrRef . current ;
72+ if ( svg === null ) { return ; }
73+ const svgData = new XMLSerializer ( ) . serializeToString ( svg ) ;
74+ const canvas = document . createElement ( "canvas" ) ;
75+ const ctx = canvas . getContext ( "2d" ) ;
76+ const img = new Image ( ) ;
77+ console . log ( "qrRef" , qrRef . current )
78+
79+ const svgBlob = new Blob ( [ svgData ] , { type : "image/svg+xml;charset=utf-8" } ) ;
80+ const url = URL . createObjectURL ( svgBlob ) ;
81+
82+ img . onload = ( ) => {
83+ // Set canvas dimensions to match SVG
84+ canvas . width = img . width ;
85+ canvas . height = img . height ;
86+ if ( ctx === null ) { return ; }
87+ ctx . drawImage ( img , 0 , 0 ) ;
88+
89+ // Copy to clipboard as a PNG
90+ canvas . toBlob ( ( blob ) => {
91+ if ( blob === null ) { return ; }
92+ const item = new ClipboardItem ( { "image/png" : blob } ) ;
93+ navigator . clipboard . write ( [ item ] ) ;
94+ } ) ;
95+
96+ URL . revokeObjectURL ( url ) ;
97+ } ;
98+
99+ img . src = url ;
100+ } catch ( err ) {
101+ console . error ( "Failed to copy qr code" , err )
102+ }
103+ }
104+
105+
106+
61107 const getEquipmentByIDResult = useQuery ( GET_EQUIPMENT_BY_ID , {
62108 variables : {
63109 id : equipmentID ,
@@ -70,6 +116,7 @@ export default function ManageEquipmentPage() {
70116
71117 const [ newInstanceName , setNewInstanceName ] = useState ( "" ) ;
72118 const [ newInstanceModal , setNewInstanceModal ] = useState ( false ) ;
119+ const [ showQrCode , setShowQrCode ] = useState < boolean > ( false ) ;
73120
74121 const [ editEquipmentModal , setEditEquipmentModal ] = useState ( false ) ;
75122
@@ -104,6 +151,19 @@ export default function ManageEquipmentPage() {
104151 >
105152 < Typography variant = { isMobile ? "h5" : "h3" } > { `Manage ${ equipment . name } ` } </ Typography >
106153 < Stack direction = { "row" } spacing = { 1 } >
154+
155+ < Button
156+ color = "info"
157+ variant = "contained"
158+ startIcon = { < QrCodeIcon /> }
159+ onClick = { ( ) => setShowQrCode ( true ) }
160+ sx = { {
161+ justifySelf : "flex-end"
162+ } }
163+ >
164+ User QR Code
165+ </ Button >
166+
107167 < Button
108168 color = "secondary"
109169 variant = "contained"
@@ -174,7 +234,28 @@ export default function ManageEquipmentPage() {
174234 </ Button >
175235 </ Stack >
176236 < MaintenanceTicketGrid equipmentID = { equipment . id } />
237+
238+
239+ { /* Equipment User Info QR Code Modal */ }
240+ < PrettyModal open = { showQrCode } onClose = { ( ) => setShowQrCode ( false ) } elevation = { 7 } >
241+ < Stack alignItems = { "center" } spacing = "10px" >
242+ < Link
243+ href = { `${ import . meta. env . VITE_ORIGIN } /app/makerspace/${ makerspaceID } /equipmentUserInfo/${ equipmentID } ` }
244+ target = { "_blank" }
245+ > User Info Page</ Link >
246+ < QRCode ref = { qrRef } value = { `${ import . meta. env . VITE_ORIGIN } /app/makerspace/${ makerspaceID } /equipmentUserInfo/${ equipmentID } ` } />
247+ < Button variant = "contained" color = "info" onClick = { copyQRCode } > Copy</ Button >
248+ </ Stack >
249+ </ PrettyModal >
250+
251+
252+
177253 </ Stack >
254+
255+
256+
257+
258+
178259 { /* Equipment Information Modal */ }
179260 < PrettyModal open = { editEquipmentModal } onClose = { ( ) => setEditEquipmentModal ( false ) } width = { "90%" } elevation = { 8 } >
180261 < EquipmentInformation equipment = { equipment } />
0 commit comments