Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/utkarsh'
Browse files Browse the repository at this point in the history
  • Loading branch information
aapav01 committed Jun 13, 2024
2 parents 86c43fe + 6411a9f commit 0d4bc68
Show file tree
Hide file tree
Showing 6 changed files with 212 additions and 78 deletions.
38 changes: 38 additions & 0 deletions app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"next": "^14.2.1",
"next-auth": "4.24.5",
"next-mdx-remote": "^4.4.1",
"pdf-lib": "^1.17.1",
"react": "18.2.0",
"react-day-picker": "^8.8.0",
"react-dom": "18.2.0",
Expand Down
Binary file added app/public/img/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
94 changes: 29 additions & 65 deletions app/src/app/(Portal)/my-profile/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import { getClient } from "@/lib/client";
import Initials from "@/lib/initials";
import { gql } from "@apollo/client";
import { getServerSession } from "next-auth";
import React from "react";
import GenerateInvoicePDF from "@/components/invoice";

type Props = {};

Expand Down Expand Up @@ -61,7 +63,7 @@ async function getPaymentDetails(session: any) {
}
}

export default async function MyProfilePage({}: Props) {
export default async function MyProfilePage({ }: Props) {
const session = await getServerSession(authOptions);
const { data, errors } = await getPaymentDetails(session);

Expand All @@ -77,11 +79,9 @@ export default async function MyProfilePage({}: Props) {
const amPM = hours >= 12 ? "PM" : "AM";
const formattedHours = hours % 12 || 12;

lastLoginFormatted = `${day < 10 ? "0" : ""}${day}/${
month < 10 ? "0" : ""
}${month}/${year} ${formattedHours}:${minutes < 10 ? "0" : ""}${minutes}:${
seconds < 10 ? "0" : ""
}${seconds} ${amPM}`;
lastLoginFormatted = `${day < 10 ? "0" : ""}${day}/${month < 10 ? "0" : ""
}${month}/${year} ${formattedHours}:${minutes < 10 ? "0" : ""}${minutes}:${seconds < 10 ? "0" : ""
}${seconds} ${amPM}`;
}

const formatDate = (inputDate: any) => {
Expand Down Expand Up @@ -176,7 +176,7 @@ export default async function MyProfilePage({}: Props) {
Enrolled Class:
</p>
<p className="font-normal text-gray-400">
{data?.me?.enrollmentSet[0].standard.name}
{data?.me?.enrollmentSet[0]?.standard?.name}
</p>
</li>
<li className="flex items-center gap-4">
Expand Down Expand Up @@ -218,9 +218,9 @@ export default async function MyProfilePage({}: Props) {
<div className="relative overflow-x-auto shadow-md sm:rounded-md">
{/* @ts-ignore */}
{data?.me?.paymentsSet &&
data?.me?.paymentsSet.filter(
(payment: any) => payment.status === "PAID"
).length > 0 ? (
data?.me?.paymentsSet.filter(
(payment: any) => payment.status === "PAID"
).length > 0 ? (
<table className="w-full text-xs sm:text-base text-left rtl:text-right text-gray-500">
<thead className="text-xs sm:text-base text-gray-700 title bg-gray-50">
<tr className="bg-gray-100">
Expand Down Expand Up @@ -262,61 +262,25 @@ export default async function MyProfilePage({}: Props) {
</tr>
</thead>
<tbody className="text-gray-600">
{data?.me?.paymentsSet
.filter((payment: any) => payment.status === "PAID")
.slice(0)
.sort(
(a: any, b: any) =>
// @ts-ignore
new Date(b.createdAt) - new Date(a.createdAt)
)
.slice(0, 5)
.map((payment: any, index: number) => (
<tr
key={index}
className="odd:bg-white even:bg-gray-50 border-b"
>
<td
align="center"
className="pl-2 sm:pl-3 py-2 sm:py-3"
>
{formatDate(payment?.createdAt)}
</td>
<td
align="center"
scope="col"
className="px-2 sm:px-3 py-2 sm:py-3"
>
{payment?.standard?.name}
</td>
<td
align="center"
scope="col"
className="px-2 sm:px-3 py-2 sm:py-3"
>
{payment?.status}
</td>
<td
align="center"
scope="col"
className="px-2 sm:px-3 py-2 sm:py-3"
>
{payment?.amount}
</td>
<td
align="center"
scope="col"
className="px-2 sm:px-3 py-2 sm:py-3"
>
<a
href="#"
className="font-medium text-blue-600 hover:underline"
>
Get Invoice
</a>
</td>
</tr>
))}
{/* @ts-ignore */}
{data?.me?.paymentsSet.filter(payment => payment.status === "PAID").slice(0).sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt)).slice(0, 5).map((payment, index) => (
<tr key={index} className="odd:bg-white even:bg-gray-50 border-b">
<td align="center" className="pl-2 sm:pl-3 py-2 sm:py-3">{formatDate(payment?.createdAt)}</td>
<td align="center" scope="col" className="px-2 sm:px-3 py-2 sm:py-3">{payment?.standard?.name}</td>
<td align="center" scope="col" className="px-2 sm:px-3 py-2 sm:py-3">{payment?.status}</td>
<td align="center" scope="col" className="px-2 sm:px-3 py-2 sm:py-3">{payment?.amount}</td>
<td align="center" scope="col" className="px-2 sm:px-3 py-2 sm:py-3"><GenerateInvoicePDF
paymentData={{
user: data?.me,
amount: payment?.amount,
createdAt: formatDate(payment?.createdAt),
orderGatewayId: payment?.orderGatewayId,
status: payment?.status,
standard: payment?.standard?.name,
}}
/></td>
</tr>
))}
</tbody>
</table>
) : (
Expand Down
24 changes: 11 additions & 13 deletions app/src/app/(Portal)/student-report/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,9 +235,9 @@ export default async function studentgrades({ searchParams }: Props) {
// Filtered data for the specific chapter
const filteredGrades = chapterId
? data?.grades.filter(
(grade: any) =>
grade?.quiz?.lessonSet[0]?.chapter?.id.toString() === chapterId
)
(grade: any) =>
grade?.quiz?.lessonSet[0]?.chapter?.id.toString() === chapterId
)
: [];

const quizChartDataForChapter = filteredGrades.reduce(
Expand Down Expand Up @@ -381,13 +381,12 @@ export default async function studentgrades({ searchParams }: Props) {
(grade: any, attemptIndex: any) => (
<span
key={`grade_${attemptIndex}`}
className={`ml-2 ${
grade > 7.5
className={`ml-2 ${grade > 7.5
? "text-green-500"
: grade >= 5
? "text-orange-400"
: "text-red-600"
}`}
? "text-orange-400"
: "text-red-600"
}`}
>
{grade}
</span>
Expand Down Expand Up @@ -495,13 +494,12 @@ export default async function studentgrades({ searchParams }: Props) {
(grade: any, attemptIndex: any) => (
<span
key={`grade_${attemptIndex}`}
className={`ml-2 ${
grade > 7.5
className={`ml-2 ${grade > 7.5
? "text-green-500"
: grade >= 5
? "text-orange-400"
: "text-red-600"
}`}
? "text-orange-400"
: "text-red-600"
}`}
>
{grade}
</span>
Expand Down
133 changes: 133 additions & 0 deletions app/src/components/invoice.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
"use client";
import React from "react";
import { PDFDocument, StandardFonts, rgb } from "pdf-lib";

type Props = {
paymentData: any;
};

export default function GenerateInvoicePDF({ paymentData }: Props) {
const handleGenerateInvoice = async () => {
const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage();

const font = await pdfDoc.embedFont(StandardFonts.Helvetica);
const fontSize = 12;
const headerFontSize = 24;
const headerColor = rgb(0, 0, 0);

const drawText = (
text: string,
x: number,
y: number,
size = fontSize,
color = rgb(0, 0, 0)
) => {
page.drawText(text, { x, y, size, font, color });
};

const drawLine = (x1: number, y1: number, x2: number, y2: number) => {
page.drawLine({
start: { x: x1, y: y1 },
end: { x: x2, y: y2 },
thickness: 1,
color: rgb(0, 0, 0),
});
};

const { user, amount, createdAt, orderGatewayId, standard } =
paymentData;

const headerText = "INVOICE";
const headerWidth = font.widthOfTextAtSize(headerText, headerFontSize);
const headerX = (page.getWidth() - headerWidth) / 2 + 200;
const headerY = page.getHeight() - 50;
drawText(headerText, headerX, headerY, headerFontSize, headerColor);
console.log(headerX);

// Company Name and Slogan
const response = await fetch("/img/logo.png");
const logoArrayBuffer = await response.arrayBuffer();
const logoPng = await pdfDoc.embedPng(logoArrayBuffer);

const logoWidth = 200; // Adjust the width as needed
const logoHeight = (logoPng.height * logoWidth) / logoPng.width;
page.drawImage(logoPng, {
x: 50,
y: 815 - logoHeight,
width: logoWidth,
height: logoHeight,
});

// Street Address, City, ST, ZIP Code
drawText("Order No. -", 50, 750);
drawText(`${orderGatewayId}`, 120, 750);

// Invoice Detail6
drawText("Date -", 425, 750);
drawText(createdAt, 465, 750);
drawText("Invoice No. -", 425, 730);
drawText("0001", 495, 730);
// Bill To
drawText("Bill To:", 50, 630);
drawText(`${user.fullName}`, 50, 610);
drawText(`${user.city},`, 50, 590);
drawText(` ${user.country}`, 100, 590);
drawText("Phone No. -", 50, 570);
drawText(`${user.phoneNumber}`, 120, 570);

// Table
const tableTop = 550;
const tableBottom = 190;
const tableLeft = 50;
const tableRight = 550;

drawLine(tableLeft, tableTop, tableRight, tableTop);
drawLine(tableLeft, tableBottom, tableRight, tableBottom);
drawLine(tableLeft, tableTop, tableLeft, tableBottom);
drawLine(tableRight, tableTop, tableRight, tableBottom);
drawLine(tableLeft + 400, tableTop, tableLeft + 400, tableBottom);
drawLine(tableLeft, tableBottom + 330, tableRight, tableBottom + 330);
drawLine(tableLeft, tableBottom + 30, tableRight, tableBottom + 30);

// Table Headers
drawText("Course Purchased", tableLeft + 10, tableTop - 20);
drawText("Amount Paid", tableLeft + 410, tableTop - 20);

// Table Rows
let rowY = tableTop - 50;
drawText(`Enrolled In ${standard}`, tableLeft + 10, rowY);
drawText(`Rs. ${amount}`, tableLeft + 410, rowY);

// Total
drawText("TOTAL", tableLeft + 10, tableBottom + 10);
drawText(`Rs.${amount}`, tableLeft + 410, tableBottom + 10);

// Footer
drawText(
"If you have any questions concerning this invoice, Write us at [email protected]",
50,
50
);
drawText("Thank you for your purchase!", 50, 30);

const pdfBytes = await pdfDoc.save();
const pdfUrl = URL.createObjectURL(
new Blob([pdfBytes], { type: "application/pdf" })
);

const link = document.createElement("a");
link.href = pdfUrl;
link.download = "Invoice.pdf";
link.click();
};

return (
<button
onClick={handleGenerateInvoice}
className="font-medium text-blue-600 hover:underline"
>
Get Invoice
</button>
);
}

0 comments on commit 0d4bc68

Please sign in to comment.