FeeReceiptPage Component
Overview
The FeeReceiptPage component is a React-based front-end module designed. It allows users to select a semester, view student information, check fee payment status, generate a PDF receipt, and download it. The component integrates with @react-pdf/renderer for PDF generation, uses Tailwind CSS for styling, and is wrapped in a custom DocumentLayout component for consistent page structure.
Dependencies
- React: For building the UI and managing state.
- @react-pdf/renderer: For generating PDF documents.
- DocumentLayout: A custom component for consistent page layout.
- PDFPreview: A custom component for previewing generated PDFs.
- FeeReceiptPDF: A custom component that defines the PDF receipt structure.
- Tailwind CSS: For styling the component.
Component Structure
The FeeReceiptPage component is organized into the following sections:
- Semester Selection: A dropdown to select a semester (1–8).
- Student Information: Displays static student details (name, roll number, programme, branch).
- Fee Payment Status: Shows whether fees are paid for the selected semester.
- PDF Preview: Displays the generated PDF receipt.
- Action Buttons: Buttons to generate the PDF and download it.
Code Explanation
Imports
import React, { useState } from "react";
import DocumentLayout from "../../components/documentSection/DocumentLayout";
import PDFPreview from "../../components/documentSection/PDFPreview";
import FeeReceiptPDF from "../../components/documentSection/FeeReceiptPDF";
import { pdf } from "@react-pdf/renderer";
- React and
useState: For managing component state. - DocumentLayout: Wraps the page content for consistent styling.
- PDFPreview: Renders the generated PDF in the browser.
- FeeReceiptPDF: A component that defines the structure of the fee receipt PDF.
- pdf: Utility from
@react-pdf/rendererto generate PDF blobs.
State Management
const [isLoading, setIsLoading] = useState(false);
const [pdfUrl, setPdfUrl] = useState(null);
const [pdfBlob, setPdfBlob] = useState(null);
const [selectedSemester, setSelectedSemester] = useState("");
isLoading: Tracks the PDF generation process to prevent multiple requests.pdfUrl: Stores the URL for the generated PDF (used inPDFPreview).pdfBlob: Stores the PDF blob for downloading.selectedSemester: Tracks the selected semester from the dropdown.
Static Data
const studentData = {
name: "JOHN SMITH DOE",
rollNo: "220103045",
programme: "BTech",
branch: "Computer Science and Engineering",
department: "Computer Science and Engineering",
feesPaid: {
1: true,
2: true,
3: false,
4: true,
5: false,
6: true,
7: true,
8: false,
},
};
const feeData = [
{ particular: "Tuition Fees", amount: "100000.00" },
{ particular: "Examination Fee", amount: "500.00" },
...
{ particular: "Total Amount", amount: "134100.00" },
{ particular: "Adjustment Amount", amount: "0.00" },
{ particular: "Payable Amount", amount: "134100.00" },
{ particular: "Remarks", amount: "null" },
];
- studentData: Hardcoded student information, including:
- Basic details (name, roll number, programme, branch, department).
feesPaid: An object mapping semesters (1–8) to payment status (truefor paid,falsefor unpaid).- feeData: An array of fee particulars with amounts, including summary rows (total, adjustment, payable amount, remarks).
Payment Status
const isPaid = selectedSemester ? studentData.feesPaid[selectedSemester] : false;
- Dynamically determines if fees are paid for the
selectedSemester. - Defaults to
falseif no semester is selected.
PDF Generation Handler
const handleGenerate = async () => {
if (!selectedSemester) return;
setIsLoading(true);
try {
const blob = await pdf(
<FeeReceiptPDF
student={studentData}
semester={selectedSemester}
feeData={feeData}
isPaid={isPaid}
/>
).toBlob();
const url = URL.createObjectURL(blob);
setPdfUrl(url);
setPdfBlob(blob);
} finally {
setIsLoading(false);
}
};
- Triggered when the "Generate Receipt" button is clicked.
- Checks if a semester is selected; if not, exits early.
- Sets
isLoadingtotrueduring generation. - Uses
pdfto generate a PDF blob from theFeeReceiptPDFcomponent, passing: student: Student data.semester: Selected semester.feeData: Fee particulars.isPaid: Payment status.- Creates a URL for the blob and updates
pdfUrlandpdfBlob. - Resets
isLoadingin thefinallyblock.
PDF Download Handler
const handleDownload = () => {
if (pdfBlob) {
const link = document.createElement("a");
link.href = URL.createObjectURL(pdfBlob);
link.download = `Fee_Receipt_Sem_${selectedSemester}.pdf`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
};
- Triggered when the "Download PDF" button is clicked.
- Checks if
pdfBlobexists. - Creates a temporary
<a>element to trigger the download. - Sets the filename to
Fee_Receipt_Sem_${selectedSemester}.pdf. - Cleans up by removing the element.
Rendering
return (
<DocumentLayout title="Fee Receipt">
<div className="max-w-3xl mx-auto space-y-6 p-6 bg-gradient-to-b from-blue-50 to-gray-100 rounded-lg shadow-lg">
<h1 className="text-3xl font-bold text-center text-blue-900 mb-6">Fee Receipt</h1>
...
</div>
</DocumentLayout>
);
- Wraps the content in
DocumentLayoutwith the title "Fee Receipt". - Uses a centered container with Tailwind styling (gradient background, shadow, rounded corners).
Semester Selection
<select
value={selectedSemester}
onChange={(e) => setSelectedSemester(e.target.value)}
className="w-full p-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
>
<option value="">Select Semester</option>
{[1, 2, 3, 4, 5, 6, 7, 8].map(num => (
<option key={num} value={num}>Semester {num}</option>
))}
</select>
- A dropdown for selecting semesters (1–8).
- Updates
selectedSemesteron change. - Styled with Tailwind (border, padding, focus ring).
Student Information
<div className="bg-white p-4 rounded-lg shadow-inner mt-6">
<h2 className="text-lg font-semibold text-gray-800 mb-3">Student Information</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<p className="text-sm text-gray-600">Name</p>
<p className="font-medium">{studentData.name}</p>
</div>
...
</div>
</div>
- Displays student details in a responsive grid (1 column on mobile, 2 on medium screens).
- Styled with Tailwind (white background, shadow, padding).
Fee Payment Status
{selectedSemester && (
<div className={`p-3 text-center rounded-lg text-lg font-semibold ${
isPaid ? "bg-green-100 text-green-800" : "bg-red-100 text-red-800"
}`}>
{isPaid ? "Fees Paid" : "Fees Not Paid"}
</div>
)}
- Conditionally renders when a semester is selected.
- Displays "Fees Paid" (green) or "Fees Not Paid" (red) based on
isPaid. - Styled with Tailwind (colored backgrounds, rounded corners).
PDF Preview
<PDFPreview pdfUrl={pdfUrl} isLoading={isLoading} />
- Renders the generated PDF using the
PDFPreviewcomponent. - Passes
pdfUrlandisLoadingas props.
Action Buttons
<div className="flex justify-center gap-4 pt-4">
<button
onClick={handleGenerate}
disabled={isLoading || !selectedSemester}
className={`... ${
isLoading || !selectedSemester
? "bg-gray-400 cursor-not-allowed"
: "bg-gradient-to-r from-blue-600 to-indigo-700 ..."
}`}
>
{isLoading ? "Generating..." : "Generate Receipt"}
</button>
{pdfUrl && (
<button
onClick={handleDownload}
className="... bg-gradient-to-r from-green-600 to-teal-700 ..."
>
Download PDF
</button>
)}
</div>
- Generate Button:
- Triggers
handleGenerate. - Disabled if
isLoadingor no semester is selected. - Shows "Generating..." during loading.
- Styled with a blue/indigo gradient and hover effects.
- Download Button:
- Appears only when
pdfUrlexists. - Triggers
handleDownload. - Styled with a green/teal gradient and hover effects.
Styling
- Tailwind CSS: Used for responsive, modern styling.
- Container:
max-w-3xl, gradient background (from-blue-50 to-gray-100), shadow, rounded corners. - Inputs: Border, focus ring, full-width.
- Cards: White background, shadow, padding.
- Buttons: Gradients, hover scaling, shadows.
- Status: Color-coded (green for paid, red for unpaid).
- Responsive Design: Uses Tailwind's responsive classes (e.g.,
md:grid-cols-2).
Assumptions
- FeeReceiptPDF: A component that accepts
student,semester,feeData, andisPaidprops to render the PDF content. - PDFPreview: A component that handles PDF rendering in the browser, accepting
pdfUrlandisLoading. - DocumentLayout: A wrapper component that accepts a
titleprop for consistent page structure. - Static Data:
studentDataandfeeDataare hardcoded; in production, these would likely be fetched from an API.
Notes
- Hardcoded Data: The component uses static data for demonstration. Replace with API calls for real-world use.
- Error Handling: Limited to
try/catchinhandleGenerate. Add error messages for failed PDF generation. - Performance: PDF generation is client-side; large datasets may impact performance.
- Security: No sensitive data is exposed, but ensure
studentDatais securely fetched in production.