PendingRequests Component
Overview
The PendingRequests component is a React component responsible for displaying and managing pending hostel transfer requests within the hostel administration system. It enables administrators to view request details and take action (approve or reject) on each request.
Component Architecture
This component uses React's state management to handle the UI for reviewing pending hostel transfer requests. It receives request data and an action handler as props from its parent component and provides a user-friendly interface for administrators to process these requests.
Technical Details
Props
| Prop | Type | Description |
|---|---|---|
requests |
Array | List of pending hostel transfer requests to display |
handleAction |
Function | Callback function to process approval/rejection actions |
State Management
The component maintains local state for handling rejection reasons:
| State Variable | Purpose |
|---|---|
rejectionReasons |
Object that stores rejection reason text for each request by ID |
Component Structure
PendingRequests
├── Empty state message (when no requests exist)
└── Request cards (for each pending request)
├── Request details (ID, roll number, hostels, reason)
├── Action buttons (Approve/Reject)
└── Rejection form (conditionally rendered)
Workflow
- Initialization:
- Component receives pending requests data via props
-
Sets up empty rejection reasons state object
-
User Interaction:
- Admin can approve a request with a single click
- Admin can begin rejection process by clicking "Reject"
- When rejection initiated, a text area appears for providing a reason
-
Admin submits the rejection with an explanation
-
State Updates:
- Local rejection reasons state is updated as admin types
- Parent component handles the API communication when actions are submitted
Code Explanation
Component Definition and State Setup
const PendingRequests = ({ requests, handleAction }) => {
const [rejectionReasons, setRejectionReasons] = useState({});
const handleLocalReasonChange = (id, value) => {
setRejectionReasons(prev => ({ ...prev, [id]: value }));
};
// ...
}
The component:
1. Accepts requests array and handleAction function as props
2. Initializes local state for tracking rejection reasons using an object where keys are request IDs
3. Defines a handler function to update the rejection reason for a specific request
Empty State Handling
if (requests.length === 0) {
return (
<div className="card bg-base-100 shadow border border-base-200 rounded-lg text-center text-gray-500 py-4">
No pending requests.
</div>
);
}
This conditional rendering displays a message when there are no pending requests to process, providing clear feedback to administrators.
Request Card Rendering
return (
<div className='card bg-base-100 shadow border border-base-200 p-6 rounded-lg'>
{requests.map(request => (
<div key={request.id} className="border rounded-lg shadow-sm mb-4 p-4">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-x-6 gap-y-1">
{/* Request information display */}
{/* ... */}
</div>
</div>
))}
</div>
);
The main render method: 1. Creates a container for all request cards 2. Maps through the requests array to create individual cards 3. Uses CSS Grid for responsive layout with a single column on small screens and two columns on larger screens
Information Display
Each request card displays several pieces of information, each styled consistently with an icon and descriptive label:
<div class="flex items-center space-x-3 py-2">
<div class="flex-shrink-0 w-10 h-10 rounded-full bg-indigo-100 flex items-center justify-center border border-indigo-200 shadow-sm">
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 384 512" class="w-5 h-5 text-indigo-600" height="1em" width="1em" xmlns="http://www.w3.org/2000/svg">
{/* Icon path */}
</svg>
</div>
<div>
<div class="text-xs font-medium text-gray-500 uppercase tracking-wider mb-0.5">Roll No</div>
<div class="text-sm font-semibold text-gray-800">{request.rollNo}</div>
</div>
</div>
Each information block includes: 1. A container with flex layout for positioning 2. An icon wrapper with consistent styling 3. A label and value display section with appropriate typography styles
Action Buttons
<div className='flex justify-left mt-2'>
<button
onClick={() => handleAction(request.id, "Approved", "", request.requestedHostel, request.rollNo)}
className="bg-green-500 max-h-10 shadow-sm text-white px-3 py-2 rounded mr-4 hover:scale-105 transition duration-200"
>
Approve
</button>
<button
onClick={() => handleLocalReasonChange(request.id, '')}
className="bg-red-500 max-h-10 shadow-sm text-white px-4 py-2 rounded hover:scale-105 transition duration-200"
>
Reject
</button>
</div>
The action buttons:
1. "Approve" - Directly calls the parent component's handleAction function with approval parameters
2. "Reject" - Initiates the rejection flow by setting an empty reason for the specific request ID
Rejection Form
{rejectionReasons.hasOwnProperty(request.id) && (
<div className="mt-2">
<textarea
value={rejectionReasons[request.id]}
onChange={(e) => handleLocalReasonChange(request.id, e.target.value)}
placeholder="Enter reason for rejection"
className="w-full shadow-sm border border-gray-300 rounded p-2 mb-2"
/>
<button
onClick={() => {
const newReason = rejectionReasons[request.id];
handleAction(request.id, "Rejected", newReason, "", request.rollNo);
}}
className="bg-red-500 shadow-sm text-white px-4 py-2 rounded hover:scale-105 transition duration-200"
>
Submit Rejection
</button>
</div>
)}
The rejection form:
1. Is conditionally rendered only when a rejection reason exists for the current request ID
2. Provides a textarea for entering the rejection reason
3. Updates the local state as the admin types
4. Includes a submit button that calls the parent's handleAction with the rejection status and reason
Key Design Patterns
Conditional Rendering
The component uses conditional rendering in two ways: 1. To show an empty state message when no requests exist 2. To show/hide the rejection reason form based on user actions
Controlled Components
The textarea for rejection reasons is a controlled component, with its value managed by React state.
State Lifting
The component follows the "state lifting" pattern where the main action handling is managed by the parent component, but local UI state (rejection reasons) is managed internally.
Responsive Design
The component uses responsive design principles with CSS Grid to adjust layout based on screen size.