Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

inplementation with Next.js #80

Open
ZuritaKelvin opened this issue Sep 10, 2024 · 8 comments
Open

inplementation with Next.js #80

ZuritaKelvin opened this issue Sep 10, 2024 · 8 comments

Comments

@ZuritaKelvin
Copy link

ZuritaKelvin commented Sep 10, 2024

I m trying to build and proyect with Next.js and this invoice generator api but i cant found any example of an inplementation with Next.js or other framework.

@syedmaazsaeed
Copy link

Can I fix this Issue? I am a Full-Stack Software Developer and work with various Tech Stack like MERN , NEXT , REACT , FLUTTER, C#.

@ZuritaKelvin
Copy link
Author

Of course!
Below I will give more details about what I am trying to do and how I have been doing it.
First in app/api/createInvoice/route.ts create the following endpoint to make the request to the API:
`import axios from 'axios';

export async function POST(req: Request) {
const apiKey = process.env.INVOICE_GENERATOR_API_KEY;
if (!apiKey) {
return Response.json({ error: 'Missing API key' }, { status: 401 });
}

try {
const invoiceData = await req.json();
if (!invoiceData) {
return Response.json({ error: 'Missing invoice data' }, { status: 400 });
}

const response = await axios.post('https://invoice-generator.com', invoiceData, {
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
});

if (!response || !response.data) {
  return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}

return Response.json({ blob: response.data });

} catch (error) {
return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}
}
I make the request from the function that is responsible for calling this endpoint, obtaining the response and converting it to a File: axios
.post('http://localhost:3000/api/createInvoice', invoice, {
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
if (!response.data) return;
if (!data.crm) return;
const crm = data.crm as File;
const { blob } = response.data;
if (!blob) return;
const pdf = new File([blob], CRM_${invoice.number}_${invoice.date}.${fileTypeByUrl(crm.name)}, {
type: 'application/pdf',
});Then I send this file along with more data to another endpoint that is responsible for sending an email with the files:formData.append('crm', data.crm);
formData.append('crmName', CRM_${invoice.number}_${invoice.date}.${fileTypeByUrl(crm.name)});
formData.append('inv', pdf);
formData.append('invName', Factura_${invoice.number}_${invoice.date}.pdf);
formData.append('clientName', data.clientName);
formData.append('dealerName', data.dealerName);
formData.append('destination', data.destination);
formData.append('date', data.date);
formData.append('invoiceNumber', invoice.number);
axios
.post('http://localhost:3000/api/send', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((response) => {
console.log(response.data);
setNotify(alert.successAlert('Factura enviada con exito', setNotify));
})
.catch((error) => {
console.error(error);
setNotify(alert.errorAlert('Error al enviar la factura', setNotify));
});`
that endpoint use Resend.
The main problem is that when receiving the email, the generated PDF shows a blank page without information.
I made this issue here assuming that the problem is when generating the pdf file or when obtaining it.
any help is welcome.thx

@syedmaazsaeed
Copy link

Open this Issue I will solve this

@ZuritaKelvin
Copy link
Author

Is this issue not already open?
The status is open. What exactly do you mean?
This is the first time I've made an issue. Could you explain?

@syedmaazsaeed
Copy link

okay let me check again. I was having a network glitch not refreshing the Page But All is ok

@syedmaazsaeed
Copy link

Your Issue : This issue is likely related to how the PDF is being generated or how the data is being fetched and sent.
Issue: The generated PDF file is showing a blank page when received via email.
let me fix this

@syedmaazsaeed
Copy link

                                            Code with fixes for generating the PDF and sending it via email. 

createInvoice/route.ts (Invoice Generation Endpoint) :

import axios from 'axios';

export async function POST(req: Request) {
const apiKey = process.env.INVOICE_GENERATOR_API_KEY;
if (!apiKey) {
return new Response(JSON.stringify({ error: 'Missing API key' }), { status: 401 });
}

try {
const invoiceData = await req.json();

console.log('Invoice Data:', invoiceData);

if (!invoiceData) {
  return new Response(JSON.stringify({ error: 'Missing invoice data' }), { status: 400 });
}


const response = await axios.post('https://invoice-generator.com', invoiceData, {
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
});


console.log('API Response:', response.data);

if (!response || !response.data) {
  return new Response(JSON.stringify({ error: 'Failed to generate invoice' }), { status: 500 });
}


return new Response(JSON.stringify({ blob: response.data }), { status: 200 });

} catch (error) {
console.error('Error generating invoice:', error);
return new Response(JSON.stringify({ error: 'Failed to generate invoice' }), { status: 500 });
}
}

  1. Frontend Call to Generate Invoice and Convert to File:

axios
.post('http://localhost:3000/api/createInvoice', invoice, {
headers: {
'Content-Type': 'application/json',
},
})
.then((response) => {
if (!response.data) return;

const { blob } = response.data;


console.log('Received Blob:', blob);

if (!blob) return;


const pdf = new File([blob], `CRM_${invoice.number}_${invoice.date}.pdf`, {
  type: 'application/pdf',
});


sendEmailWithInvoice(pdf);

})
.catch((error) => {
console.error('Error generating PDF:', error);
});

Email Sending Function:

function sendEmailWithInvoice(pdf) {
const formData = new FormData();
formData.append('crm', data.crm);
formData.append('crmName', CRM_${invoice.number}_${invoice.date}.pdf);
formData.append('inv', pdf);
formData.append('invName', Factura_${invoice.number}_${invoice.date}.pdf);
formData.append('clientName', data.clientName);
formData.append('dealerName', data.dealerName);
formData.append('destination', data.destination);
formData.append('date', data.date);
formData.append('invoiceNumber', invoice.number);

axios
.post('http://localhost:3000/api/send', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
})
.then((response) => {
console.log('Invoice sent successfully:', response.data);
setNotify(alert.successAlert('Factura enviada con exito', setNotify));
})
.catch((error) => {
console.error('Error sending the invoice:', error);
setNotify(alert.errorAlert('Error al enviar la factura', setNotify));
});
}

I have made the necessary fixes based on your requirements for generating the PDF and sending it via email. Check this and run this In Your Coding Environment. Copy this code and run it in your project. Let me know if this resolves the issue, or if you encounter any other problems.

@ZuritaKelvin
Copy link
Author

Thank you very much for your contribution.
I just found the solution on my own but I will check if this way works and I will let you know.
In the meantime this has been the solution that worked for me to receive and be able to view the pdf correctly:

First the endpoint returns the file encrypted on base63 string:
`import axios from 'axios';

export async function POST(req: Request) {
const apiKey = process.env.INVOICE_GENERATOR_API_KEY;
if (!apiKey) {
return Response.json({ error: 'Missing API key' }, { status: 401 });
}

try {
const invoiceData = await req.json();
if (!invoiceData) {
return Response.json({ error: 'Missing invoice data' }, { status: 400 });
}

const response = await axios.post('https://invoice-generator.com', invoiceData, {
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
    'Content-Disposition': 'attachment; filename="invoice.pdf"',
  },
  responseType: 'arraybuffer',
});

if (!response || !response.data) {
  return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}

const invoiceBuffer = Buffer.from(response.data);
const invoiceBase64 = invoiceBuffer.toString('base64');

return Response.json(invoiceBase64);

} catch (error) {
return Response.json({ error: 'Failed to generate invoice' }, { status: 500 });
}
}
`
I directly pass the response to the other endpoint:

const file = response.data; formData.append('inv', file);
Finally i convert the stringBase64 to a Buffer and send it in the POST request:
const invoiceFile = formData.get('inv') as string; const pdfFile = Buffer.from(invoiceFile, 'base64');
I'm surprised that someone helped me so quickly after creating the issue. Many thanks to @syedmaazsaeed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants