Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 | 23x 23x 23x 23x 23x 23x 10x 10x 1x 1x 10x 2x 8x 1x 1x 7x 7x 7x 7x 7x 4x 3x 3x 3x 3x 3x 1x 2x 1x 3x 7x 7x 7x 2x 23x | import { useState, useEffect } from 'react' import { getUserQr } from '../services/billingService' import { useAuthStore } from '../stores/useAuthStore' import { useCustomSnackbar } from './useCustomSnackbar' import { useTranslation } from 'react-i18next' import { logError } from '../utils/logger' export function useFetchTicketQr(qrFilename: string | null) { const token = useAuthStore(s => s.authToken) const { notify } = useCustomSnackbar() const { t } = useTranslation('tickets') const [qrUrl, setQrUrl] = useState<string | null>(null) const [loading, setLoading] = useState(false) useEffect(() => { let canceled = false // Nettoyage de l’URL précédente if (qrUrl) { URL.revokeObjectURL(qrUrl) setQrUrl(null) } if (!qrFilename) { return } if (!token) { notify(t('errors.not_authenticated'), 'warning') return } const filename = qrFilename.replace(/^.*[\\/]/, '') const fetchQr = async () => { setLoading(true) try { const blob = await getUserQr(filename, token) if (canceled) return const url = URL.createObjectURL(blob) setQrUrl(url) } catch (err: any) { logError('useFetchTicketQr', err) let msg = t('errors.qr_fetch_failed') if (err.response?.status === 404) { msg = t('errors.qr_not_found') } else if (err.response?.status === 401) { msg = t('errors.unauthorized') } notify(msg, 'error') } finally { if (!canceled) setLoading(false) } } fetchQr() return () => { canceled = true } }, [qrFilename, token]) return { qrUrl, loading } } |