My task is to use a query, send the mandatory variables and get a pdf from the BE.
Right now, I have the code but I can’t get the pdf downloaded.
In the network tab I can see my request but nothing in the response.
This is the request:
query getCollectionReportOverview(
$filterReportCollectionOverview: ReportCollectionOverviewInput!
) {
getCollectionReportOverview(
filterReportCollectionOverview: $filterReportCollectionOverview
)
}
{
"filterReportCollectionOverview": {
"collectionNames": [
"2024 copy"
],
"collectionNumbers": [
49464
],
"brandName": "fake it",
"createdByName": "John doe",
"createdBy": "125256",
"sortby": "masterCategoryName"
}
}
I’m not entirely sure about the code for getting the pdf and why the query isn’t working as it should.
Here is my code
interface ButtonProps {
isLargeScreen: boolean;
onClick: () => void;
isOptionSelected: boolean;
sortbyValue: string;
collectionNames: Array<string>;
collectionNumbers: Array<number>;
brandName: string;
}
const CreateViewButton = ({ isLargeScreen, onClick, isOptionSelected }: ButtonProps): ReactElement => (
<Button size={isLargeScreen ? 'large' : 'small'} disabled={!isOptionSelected} onClick={(): void => void onClick()}>
view report
</Button>
);
export const ReportsFooter = ({
isOptionSelected,
handleOnClearAll,
sortby,
collectionNames,
collectionNumbers,
brandName,
}: {
isOptionSelected: boolean;
handleOnClearAll: () => void;
sortby: string;
collectionNames: Array<string>;
collectionNumbers: Array<number>;
brandName: string;
}): ReactElement => {
const theme = useTheme();
const isLargeScreen = useMediaQuery(theme.breakpoints.up('lg'));
const [loading, setLoading] = useState(false);
const { buyingProfile } = useProfiles();
console.log(loading, 'loading');
const [getCollectionReportOverview, { error }] = useLazyQuery(
GET_COLLECTION_REPORT_OVERVIEW,
{
onCompleted: (result) => {
setLoading(false);
console.log('Request completed');
const base64Pdf = result?.data?.getCollectionReportOverview;
console.log(base64Pdf); // Add this log
if (base64Pdf) {
downloadPdf(base64Pdf);
}
},
onError: (error) => {
setLoading(false);
console.error('GraphQL error:', error); // Add this log
},
fetchPolicy: 'network-only',
context: { clientName: GraphClientNames['reports'] },
}
);
const filterReportCollectionOverview = {
collectionNames: collectionNames,
collectionNumbers: collectionNumbers,
brandName: brandName,
createdByName: buyingProfile?.name,
createdBy: buyingProfile?.userNumber,
sortby: sortby,
};
const handleClickCreateViewButton = (): void => {
console.log('Button clicked'); // Add this log
setLoading(true);
getCollectionReportOverview({
variables: {
filterReportCollectionOverview: filterReportCollectionOverview,
},
});
};
const downloadPdf = (base64Pdf: string, fileName = 'report.pdf') => {
console.log('Downloading PDF'); // Add this log
const blob = b64toBlob(base64Pdf, 'application/pdf');
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
link.click();
URL.revokeObjectURL(url);
};
const b64toBlob = (base64: string, type = 'application/octet-stream') => {
const byteCharacters = atob(base64);
const byteArrays: Array<number> = [];
for (let offset = 0; offset < byteCharacters.length; offset += 512) {
const slice = byteCharacters.slice(offset, offset + 512);
const byteNumbers = new Array<number>(slice.length);
for (let i = 0; i < slice.length; i++) {
byteNumbers[i] = slice.charCodeAt(i);
}
byteArrays.push(...byteNumbers);
}
const blob = new Blob([new Uint8Array(byteArrays)], { type });
return blob;
};
const hintComponent = (
<Box
sx={{
display: 'flex',
flexDirection: 'column',
flex: '1',
alignItems: 'center',
}}
>
<Box
sx={{
display: 'flex',
alignItems: 'center',
flexDirection: 'row',
justifyContent: 'space-between',
flex: '1',
}}
>
<Typography variant={isLargeScreen ? 'body.default' : 'bodySmall.default'} sx={{ whiteSpace: 'nowrap' }}>
* required:
</Typography>
<Typography variant={isLargeScreen ? 'body.highlight' : 'bodySmall.highlight'} sx={{ paddingLeft: 1, whiteSpace: 'nowrap' }}>
{isOptionSelected ? '1/1' : '0/1'}
</Typography>
</Box>
<Typography variant='captions.default' sx={{ paddingLeft: 1, whiteSpace: 'nowrap' }}>
{isOptionSelected ? "You're good to go" : 'Select a Collection'}
</Typography>
</Box>
);
return (
<ProcessFooter
leftSideComponents={[
<Button
key='cancel-button'
variant="outlined"
size={isLargeScreen ? 'large' : 'small'}
disabled={!isOptionSelected}
onClick={handleOnClearAll}
>
<CrossIcon style={{ padding: '0px 12px 0px 0px' }} />
clear all
</Button>,
]}
hint={hintComponent}
rightSideComponents={[
loading ? (
<Stack
justifyContent="center"
alignItems="center"
spacing={5}
>
<LoadingSpinner />
<Typography variant="headings.h4" textAlign="center">
generating report
</Typography>
</Stack>
) : (
<CreateViewButton
key='create-orders-button'
isLargeScreen={isLargeScreen}
isOptionSelected={isOptionSelected}
sortbyValue={sortby}
collectionNames={collectionNames}
collectionNumbers={collectionNumbers}
brandName={brandName}
onClick={handleClickCreateViewButton}
/>
),
]}
/>
);
};
If someone can guide me and counsel me as I’m a bit lost and confused.
New contributor