Skip to content

Conversation

@shanurajpoot001
Copy link

@shanurajpoot001 shanurajpoot001 commented Aug 7, 2025

🎉 Certificate Management Page UI - Feature Implementation

�� Issue Reference

Fixes: #72 - [FEATURE]: Certificate page UI

🚀 Overview

This PR implements a comprehensive Certificate Management page that provides users with a modern, intuitive interface to view, search, filter, and manage all their generated certificates in one centralized location.

✨ Features Implemented

🎨 Modern UI/UX Design

  • Glassmorphism Design: Beautiful backdrop blur effects with transparent overlays
  • Responsive Layout: Fully responsive design that works on all device sizes
  • Smooth Animations: Framer Motion powered animations for enhanced user experience
  • Dark Theme: Consistent with the existing HonorBox design system

🔍 Advanced Search & Filter

  • Real-time Search: Search certificates by name, email, or unique ID
  • Type Filtering: Filter by certificate types (Participation, Completion, Excellence, Achievement)
  • Instant Results: Live filtering as you type

📋 Certificate Management

  • Certificate Grid: Card-based layout showing all certificates
  • Quick Actions: View, Download, and Share buttons for each certificate
  • Detailed Modal: Comprehensive certificate details in a beautiful modal
  • Status Indicators: Visual status indicators for certificate validity

🎯 Key Functionalities

  • View Certificates: Click to view detailed certificate information
  • Download Certificates: Direct download functionality for certificate images
  • Share Certificates: Native sharing API with clipboard fallback
  • Create New: Quick access to certificate generation page

🛠 Technical Implementation

Frontend Components

  • Certificate.jsx: Main certificate management component
  • Updated App.jsx: Added new route for /certificates
  • Updated Navbar.jsx: Added navigation link to Certificates page
  • Updated README.md: Documentation updates

Backend Integration

  • API Endpoints: Utilizes existing /api/certificates endpoint
  • Certificate Verification: Integrates with certificate verification system
  • Download Functionality: Leverages existing certificate generation endpoints

Design System

  • Color Coding: Different colors for different certificate types
  • Icon System: Emoji-based icons for certificate types
  • Loading States: Beautiful loading animations
  • Empty States: Helpful empty state with call-to-action

�� Responsive Design

  • Mobile First: Optimized for mobile devices
  • Tablet Support: Responsive grid layout
  • Desktop Experience: Full-featured desktop interface
  • Touch Friendly: Large touch targets for mobile users

�� UI/UX Enhancements

  • Hover Effects: Subtle hover animations on cards
  • Modal Design: Beautiful certificate details modal
  • Loading Spinners: Animated loading indicators
  • Error Handling: Graceful error states
  • Accessibility: Proper ARIA labels and keyboard navigation

🔧 Code Quality

  • React Hooks: Modern React patterns with useState and useEffect
  • Error Handling: Comprehensive error handling for API calls
  • Performance: Optimized rendering with proper key props
  • Type Safety: Proper prop handling and state management

�� Testing Scenarios

  • ✅ Search functionality works correctly
  • ✅ Filter by certificate type works
  • ✅ View certificate details modal opens
  • ✅ Download functionality works
  • ✅ Share functionality works (native API + clipboard fallback)
  • ✅ Responsive design on all screen sizes
  • ✅ Loading states display correctly
  • ✅ Empty states show appropriate messages

�� Deployment Ready

  • No Breaking Changes: Backward compatible with existing features
  • Environment Variables: Uses existing VITE_BACKEND_URL
  • Dependencies: All required packages already installed
  • Build Ready: Ready for production deployment

📝 Documentation Updates

  • Updated README.md with new feature description
  • Added component documentation
  • Updated project structure documentation

🎯 User Experience Improvements

  • Faster Certificate Access: No need to remember certificate IDs
  • Better Organization: All certificates in one place
  • Quick Actions: One-click download and share
  • Visual Feedback: Clear status indicators and loading states

�� Related Links

🧪 Testing Instructions

  1. Navigate to /certificates page
  2. Test search functionality with different terms
  3. Test filter dropdown with different certificate types
  4. Click "View" on any certificate to test modal
  5. Test download functionality
  6. Test share functionality
  7. Test responsive design on different screen sizes

📸 Screenshots

[Screenshots will be added after deployment]


Ready for Review! 🚀

This implementation provides a complete certificate management solution that enhances the user experience significantly while maintaining the existing design system and code quality standards.

Summary by CodeRabbit

  • New Features

    • Introduced a comprehensive Certificate Management page with search, filter, view, download, and share capabilities for certificates.
    • Added a modal for detailed certificate information and actions.
    • Enhanced navigation by adding a "Certificates" link to the Navbar.
  • Documentation

    • Updated the README to describe the new certificate management feature and clarify component roles.

shanu pratap rajpoot added 2 commits August 8, 2025 00:12
…rtificate management interface with search, filter, and CRUD operations - Add modern responsive design with animations and glassmorphism effects - Include certificate viewing modal with detailed information - Add download and share functionality for certificates - Update navigation to include Certificates page - Enhance user experience with loading states and empty states - Fix issue RamakrushnaBiswal#72: Certificate page UI implementation
…rtificate management interface with search, filter, and CRUD operations - Add modern responsive design with animations and glassmorphism effects - Include certificate viewing modal with detailed information - Add download and share functionality for certificates - Update navigation to include Certificates page - Enhance user experience with loading states and empty states - Fix issue RamakrushnaBiswal#72: Certificate page UI implementation
@vercel
Copy link

vercel bot commented Aug 7, 2025

Someone is attempting to deploy a commit to the bunty's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Aug 7, 2025

Walkthrough

A new Certificate Management UI is introduced in the frontend, including a dedicated React component, new navigation route, and updates to documentation and navigation. The component provides search, filter, view, download, and share features for certificates. The Navbar and README are updated to reflect these additions. No backend or unrelated changes are present.

Changes

Cohort / File(s) Change Summary
Certificate Management Feature
Frontend/src/components/Certificate.jsx
Adds a new React component for certificate management, supporting search, filter, view, download, and share features with a modern UI, modal details, and animations.
Routing Integration
Frontend/src/App.jsx
Imports the new Certificate component and registers a /certificates route to render it.
Navigation Update
Frontend/src/components/Navbar.jsx
Adds "Certificates" navigation link to both desktop and mobile menus in the Navbar.
Documentation Update
Frontend/README.md
Updates documentation to include the new certificate management feature and component in the project structure.
Unrelated Help Doc
tatus
Adds a help summary document for the "less" command, unrelated to the certificate management feature.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Navbar
    participant Router
    participant CertificateComponent
    participant BackendAPI

    User->>Navbar: Clicks "Certificates"
    Navbar->>Router: Navigates to /certificates
    Router->>CertificateComponent: Renders Certificate component
    CertificateComponent->>BackendAPI: Fetch certificates
    BackendAPI-->>CertificateComponent: Returns certificate data
    CertificateComponent-->>User: Displays certificate list with search/filter
    User->>CertificateComponent: Selects certificate/view details/download/share
    CertificateComponent->>BackendAPI: (If download) Fetch certificate image
    CertificateComponent-->>User: Shows modal/download/share actions
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15–20 minutes

Assessment against linked issues

Objective Addressed Explanation
Implement Certificate page UI with search, filter, view, download, share, and modal details (#72)
Add navigation to Certificate page (#72)
Update documentation to reflect new certificate management feature (#72)

Assessment against linked issues: Out-of-scope changes

Code Change Explanation
Addition of "less" command help summary document (tatus) This document is unrelated to the certificate management UI or any objectives in issue #72.

Suggested labels

enhancement, Level 3, GSSOC-25, Backend

Poem

A brand new page for certs is here,
With search and filters, crystal clear.
Download, share, or just admire—
Animated cards to inspire!
Navbar shines with a brand-new link,
This bunny’s proud—what do you think?
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🔭 Outside diff range comments (2)
tatus (1)

1-315: Remove unrelated file from the PR.

This file contains help documentation for the "less" command-line pager utility, which is completely unrelated to the Certificate Management UI feature being implemented in this PR. This appears to be an accidentally committed file that should be removed.

-Delete the entire file as it's not related to the PR's purpose
h origin main (1)

1-2: Remove accidentally committed git output.

This file appears to contain git log output showing commit information, which should not be committed to the repository. This looks like accidental output from a git log or similar command.

Remove this file as it's not meant to be part of the codebase.

🧹 Nitpick comments (2)
Frontend/src/components/Certificate.jsx (2)

106-110: Avoid mixing inline styles with Tailwind classes.

Using both inline styles and Tailwind classes reduces maintainability and consistency.

-<div style={{ width: '100%', minHeight: '100vh', position: 'relative', overflow: 'visible' }}>
-  <div style={{ position: 'absolute', inset: 0, zIndex: 0 }}>
+<div className="w-full min-h-screen relative overflow-visible">
+  <div className="absolute inset-0 z-0">
     <DarkVeil />
   </div>
-  <div style={{ position: 'relative', zIndex: 1 }} className="min-h-screen py-12 px-4">
+  <div className="relative z-10 min-h-screen py-12 px-4">

1-336: Consider adding TypeScript or PropTypes for type safety.

The component lacks type definitions which could lead to runtime errors.

Consider migrating to TypeScript or adding PropTypes to ensure type safety. Would you like me to help generate TypeScript interfaces for this component?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 577d56c and 7c4dd6e.

📒 Files selected for processing (6)
  • Frontend/README.md (2 hunks)
  • Frontend/src/App.jsx (2 hunks)
  • Frontend/src/components/Certificate.jsx (1 hunks)
  • Frontend/src/components/Navbar.jsx (2 hunks)
  • h origin main (1 hunks)
  • tatus (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:0-0
Timestamp: 2025-08-04T18:51:46.896Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the password change functionality in confirmChangePassword() intentionally only logs to console as this was a UI-only enhancement PR, with backend integration planned for future implementation.
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:153-157
Timestamp: 2025-08-04T18:52:03.885Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the account deletion functionality in handleDeleteAccount() intentionally only logs to console as this was a UI-only enhancement PR, with backend integration planned for future implementation.
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:0-0
Timestamp: 2025-08-04T19:02:27.830Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the email change functionality includes a confirmation modal triggered by clicking the "Change" button, which calls setShowConfirmEmailChange(true) and displays a modal asking for user confirmation before applying the email change via handleEmailChange().
📚 Learning: 2025-08-04T18:51:46.896Z
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:0-0
Timestamp: 2025-08-04T18:51:46.896Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the password change functionality in confirmChangePassword() intentionally only logs to console as this was a UI-only enhancement PR, with backend integration planned for future implementation.

Applied to files:

  • Frontend/src/components/Navbar.jsx
  • h origin main
  • Frontend/README.md
  • Frontend/src/App.jsx
  • Frontend/src/components/Certificate.jsx
📚 Learning: 2025-08-04T18:52:03.885Z
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:153-157
Timestamp: 2025-08-04T18:52:03.885Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the account deletion functionality in handleDeleteAccount() intentionally only logs to console as this was a UI-only enhancement PR, with backend integration planned for future implementation.

Applied to files:

  • Frontend/src/components/Navbar.jsx
  • Frontend/README.md
  • Frontend/src/App.jsx
  • Frontend/src/components/Certificate.jsx
📚 Learning: 2025-08-04T19:02:27.830Z
Learnt from: cherylpinto
PR: RamakrushnaBiswal/HonorBox#79
File: Frontend/src/components/Navbar.jsx:0-0
Timestamp: 2025-08-04T19:02:27.830Z
Learning: In the HonorBox project Frontend/src/components/Navbar.jsx, the email change functionality includes a confirmation modal triggered by clicking the "Change" button, which calls setShowConfirmEmailChange(true) and displays a modal asking for user confirmation before applying the email change via handleEmailChange().

Applied to files:

  • Frontend/src/components/Navbar.jsx
  • Frontend/README.md
  • Frontend/src/App.jsx
  • Frontend/src/components/Certificate.jsx
🔇 Additional comments (6)
Frontend/src/components/Navbar.jsx (2)

114-119: LGTM!

The new "Certificates" navigation link is properly integrated into the desktop menu with consistent styling and hover effects matching the existing "Home" link.


163-169: LGTM!

The "Certificates" link is correctly added to the mobile menu with proper onClick handler to close the menu after navigation, maintaining consistency with the existing mobile navigation pattern.

Frontend/src/App.jsx (2)

5-5: LGTM!

The Certificate component import follows the established pattern and is correctly placed with other component imports.


53-53: LGTM!

The new route for "/certificates" is properly configured and follows the existing route structure. The path is logical and the component reference is correct.

Frontend/README.md (2)

6-6: LGTM!

The Certificate Management feature is properly documented with a clear description of its capabilities (view, search, filter, and manage certificates).


47-50: LGTM!

The project structure documentation is updated correctly to include the new Certificate.jsx component and accurately describes its purpose as the certificate management page. The correction to the Generate.jsx comment also improves clarity.

Comment on lines +20 to +32
const fetchCertificates = async () => {
try {
const response = await fetch(`${BACKEND_URL}/api/certificates`);
if (response.ok) {
const data = await response.json();
setCertificates(data);
}
} catch (error) {
console.error("Error fetching certificates:", error);
} finally {
setLoading(false);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Improve error handling and add authentication.

The fetch operation has several issues:

  1. Errors are only logged to console - users won't be notified if the fetch fails
  2. No authentication headers are being sent with the request
  3. Response data is not validated before setting state

Consider adding error state management and authentication:

 const fetchCertificates = async () => {
   try {
-    const response = await fetch(`${BACKEND_URL}/api/certificates`);
+    const response = await fetch(`${BACKEND_URL}/api/certificates`, {
+      headers: {
+        'Authorization': `Bearer ${localStorage.getItem('token')}`, // Add auth if required
+        'Content-Type': 'application/json',
+      },
+    });
     if (response.ok) {
       const data = await response.json();
+      // Validate data structure
+      if (Array.isArray(data)) {
         setCertificates(data);
+      } else {
+        console.error("Invalid data format received");
+        // Set error state
+      }
+    } else {
+      console.error(`Failed to fetch: ${response.status}`);
+      // Set error state
     }
   } catch (error) {
     console.error("Error fetching certificates:", error);
+    // Set error state to show user-friendly message
   } finally {
     setLoading(false);
   }
 };

Let me verify if authentication is implemented elsewhere in the codebase:


🏁 Script executed:

#!/bin/bash
# Check if authentication is used in other API calls
rg -A 3 "fetch.*api" --type jsx --type js

Length of output: 71


🏁 Script executed:

#!/bin/bash
# Search for fetch calls and any usage of Authorization headers in .js and .jsx files
rg -n "fetch" --glob "*.{js,jsx}" -A3
rg -n "Authorization" --glob "*.{js,jsx}"

Length of output: 5913


#!/bin/bash
# Display the authentication utility implementation
sed -n '1,200p' Frontend/src/utils/auth.js

🏁 Script executed:

#!/bin/bash
# Display the authentication utility to see how auth headers are applied
sed -n '1,200p' Frontend/src/utils/auth.js

Length of output: 1096


Use the existing authenticatedFetch, add error state, and validate the response in Certificate.jsx

To ensure users see failures, credentials are sent, and data is well-formed, update fetchCertificates as follows:

• In Frontend/src/components/Certificate.jsx (around lines 1–19), import and track an error state alongside loading:

import { authenticatedFetch } from '../utils/auth';
const [certificates, setCertificates] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState(null);

• Rewrite fetchCertificates (lines 20–32) to:

- const fetchCertificates = async () => {
-   try {
-     const response = await fetch(`${BACKEND_URL}/api/certificates`);
-     if (response.ok) {
-       const data = await response.json();
-       setCertificates(data);
-     }
-   } catch (error) {
-     console.error("Error fetching certificates:", error);
-   } finally {
-     setLoading(false);
-   }
- };
+ const fetchCertificates = async () => {
+   setLoading(true);
+   setError(null);
+   try {
+     const res = await authenticatedFetch(`${BACKEND_URL}/api/certificates`);
+     if (!res.ok) {
+       throw new Error(`Fetch failed: ${res.status} ${res.statusText}`);
+     }
+     const data = await res.json();
+     if (!Array.isArray(data)) {
+       throw new Error('Unexpected response format');
+     }
+     setCertificates(data);
+   } catch (err) {
+     console.error('Error fetching certificates:', err);
+     setError(err.message);
+   } finally {
+     setLoading(false);
+   }
+ };

• In your render, show a user-friendly message when error is non-null.

These changes:

  1. Reuse the project’s authenticatedFetch (adds the Bearer token).
  2. Expose failures via an error state.
  3. Guard against invalid payloads.
🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx around lines 1 to 32, import
authenticatedFetch from '../utils/auth' and add an error state using
useState(null) alongside certificates and loading states. Update
fetchCertificates to use authenticatedFetch instead of fetch, set error state to
null at the start, and after fetching, validate the response data before setting
certificates; if invalid, set an appropriate error message. In the catch block,
set the error state with the caught error message. Finally, in the component
render, display a user-friendly error message when error state is non-null to
inform users of failures.

Comment on lines +34 to +40
const filteredCertificates = certificates.filter(cert => {
const matchesSearch = cert.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
cert.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
cert.uniqueId.toLowerCase().includes(searchTerm.toLowerCase());
const matchesFilter = filterType === "all" || cert.certificateType === filterType;
return matchesSearch && matchesFilter;
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Add null safety checks and optimize filtering with useMemo.

The filtering logic could throw errors if certificate properties are undefined and should be memoized for better performance.

+import { useState, useEffect, useMemo } from "react";

-const filteredCertificates = certificates.filter(cert => {
-  const matchesSearch = cert.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
-                       cert.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
-                       cert.uniqueId.toLowerCase().includes(searchTerm.toLowerCase());
+const filteredCertificates = useMemo(() => {
+  return certificates.filter(cert => {
+    const matchesSearch = 
+      (cert.name?.toLowerCase().includes(searchTerm.toLowerCase()) || false) ||
+      (cert.email?.toLowerCase().includes(searchTerm.toLowerCase()) || false) ||
+      (cert.uniqueId?.toLowerCase().includes(searchTerm.toLowerCase()) || false);
   const matchesFilter = filterType === "all" || cert.certificateType === filterType;
   return matchesSearch && matchesFilter;
-});
+  });
+}, [certificates, searchTerm, filterType]);

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx around lines 34 to 40, the filtering
logic lacks null safety checks for certificate properties, which can cause
runtime errors if any property is undefined. Add checks to ensure cert.name,
cert.email, and cert.uniqueId exist before calling toLowerCase on them.
Additionally, wrap the filtering logic inside a useMemo hook with dependencies
on certificates, searchTerm, and filterType to optimize performance by memoizing
the filtered results.

Comment on lines +47 to +64
const handleDownload = async (cert) => {
try {
const response = await fetch(`${BACKEND_URL}/api/certificate/${cert.uniqueId}`);
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `certificate-${cert.uniqueId}.png`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
} catch (error) {
console.error("Error downloading certificate:", error);
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Improve download error handling and add loading state.

The download function needs better error handling and user feedback.

-const handleDownload = async (cert) => {
+const [downloading, setDownloading] = useState(false);
+
+const handleDownload = async (cert) => {
+  setDownloading(true);
   try {
     const response = await fetch(`${BACKEND_URL}/api/certificate/${cert.uniqueId}`);
     if (response.ok) {
       const blob = await response.blob();
       const url = window.URL.createObjectURL(blob);
       const a = document.createElement('a');
       a.href = url;
       a.download = `certificate-${cert.uniqueId}.png`;
       document.body.appendChild(a);
       a.click();
-      window.URL.revokeObjectURL(url);
       document.body.removeChild(a);
+      window.URL.revokeObjectURL(url);
+    } else {
+      throw new Error(`Download failed: ${response.status}`);
     }
   } catch (error) {
     console.error("Error downloading certificate:", error);
+    // Show user-friendly error message instead of just logging
+  } finally {
+    setDownloading(false);
   }
 };
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleDownload = async (cert) => {
try {
const response = await fetch(`${BACKEND_URL}/api/certificate/${cert.uniqueId}`);
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `certificate-${cert.uniqueId}.png`;
document.body.appendChild(a);
a.click();
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
}
} catch (error) {
console.error("Error downloading certificate:", error);
}
};
// add loading state for download
const [downloading, setDownloading] = useState(false);
const handleDownload = async (cert) => {
setDownloading(true);
try {
const response = await fetch(`${BACKEND_URL}/api/certificate/${cert.uniqueId}`);
if (response.ok) {
const blob = await response.blob();
const url = window.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `certificate-${cert.uniqueId}.png`;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
} else {
throw new Error(`Download failed: ${response.status}`);
}
} catch (error) {
console.error("Error downloading certificate:", error);
// TODO: show user‐friendly error message (e.g. set an error state or toast)
} finally {
setDownloading(false);
}
};
🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx around lines 47 to 64, improve the
handleDownload function by adding a loading state to indicate progress to the
user and enhance error handling by providing user feedback on failure. Implement
a state variable to track loading, set it to true at the start of the download
and false at the end or on error, and display a loading indicator in the UI.
Also, handle non-ok responses by throwing an error or notifying the user, and
ensure errors are caught and communicated clearly.

Comment on lines +66 to +83
const handleShare = async (cert) => {
const shareUrl = `${BACKEND_URL}/api/certificate/${cert.uniqueId}`;
if (navigator.share) {
try {
await navigator.share({
title: `Certificate - ${cert.name}`,
text: `Check out this certificate for ${cert.name}`,
url: shareUrl
});
} catch (error) {
console.error("Error sharing:", error);
}
} else {
// Fallback to copying to clipboard
navigator.clipboard.writeText(shareUrl);
alert("Certificate link copied to clipboard!");
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

⚠️ Potential issue

Replace alert() with proper notification system and handle clipboard errors.

Using alert() provides poor UX. Also, clipboard operations can fail and should be handled properly.

 const handleShare = async (cert) => {
   const shareUrl = `${BACKEND_URL}/api/certificate/${cert.uniqueId}`;
   if (navigator.share) {
     try {
       await navigator.share({
         title: `Certificate - ${cert.name}`,
         text: `Check out this certificate for ${cert.name}`,
         url: shareUrl
       });
     } catch (error) {
-      console.error("Error sharing:", error);
+      if (error.name !== 'AbortError') {
+        console.error("Error sharing:", error);
+        // Show error notification
+      }
     }
   } else {
     // Fallback to copying to clipboard
-    navigator.clipboard.writeText(shareUrl);
-    alert("Certificate link copied to clipboard!");
+    try {
+      await navigator.clipboard.writeText(shareUrl);
+      // Use a toast notification library instead of alert
+      // Example: showToast("Certificate link copied to clipboard!");
+    } catch (error) {
+      console.error("Error copying to clipboard:", error);
+      // Show error notification
+    }
   }
 };

Consider using a toast notification library like react-toastify for better UX.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleShare = async (cert) => {
const shareUrl = `${BACKEND_URL}/api/certificate/${cert.uniqueId}`;
if (navigator.share) {
try {
await navigator.share({
title: `Certificate - ${cert.name}`,
text: `Check out this certificate for ${cert.name}`,
url: shareUrl
});
} catch (error) {
console.error("Error sharing:", error);
}
} else {
// Fallback to copying to clipboard
navigator.clipboard.writeText(shareUrl);
alert("Certificate link copied to clipboard!");
}
};
const handleShare = async (cert) => {
const shareUrl = `${BACKEND_URL}/api/certificate/${cert.uniqueId}`;
if (navigator.share) {
try {
await navigator.share({
title: `Certificate - ${cert.name}`,
text: `Check out this certificate for ${cert.name}`,
url: shareUrl
});
} catch (error) {
if (error.name !== 'AbortError') {
console.error("Error sharing:", error);
// Show error notification
}
}
} else {
// Fallback to copying to clipboard
try {
await navigator.clipboard.writeText(shareUrl);
// Use a toast notification library instead of alert
// Example: showToast("Certificate link copied to clipboard!");
} catch (error) {
console.error("Error copying to clipboard:", error);
// Show error notification
}
}
};
🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx around lines 66 to 83, replace the
alert() call used for notifying the user about the copied certificate link with
a proper toast notification from a library like react-toastify. Additionally,
add error handling for the clipboard.writeText operation by using try-catch or
promise catch to handle failures gracefully and show an error toast notification
if copying fails.

<option value="Achievement">Achievement</option>
</select>
<button
onClick={() => window.location.href = '/generate'}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Use React Router for navigation instead of window.location.href.

Direct navigation with window.location.href causes full page reload, losing application state.

+import { useNavigate } from 'react-router-dom';

+const navigate = useNavigate();

 <button
-  onClick={() => window.location.href = '/generate'}
+  onClick={() => navigate('/generate')}

Also applies to: 188-188

🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx at lines 158 and 188, replace the
direct navigation using window.location.href with React Router's navigation
method to prevent full page reloads and preserve application state. Import the
useNavigate hook from react-router-dom, initialize it in the component, and use
the navigate function inside the onClick handlers to navigate to '/generate'
instead of setting window.location.href.

>
<div className="flex items-start justify-between mb-4">
<div className="flex items-center gap-3">
<div className={`text-2xl ${getCertificateIcon(cert.certificateType)}`}></div>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix emoji display issue in certificate icon.

The template literal syntax is incorrect for displaying the emoji.

-<div className={`text-2xl ${getCertificateIcon(cert.certificateType)}`}></div>
+<div className="text-2xl">{getCertificateIcon(cert.certificateType)}</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div className={`text-2xl ${getCertificateIcon(cert.certificateType)}`}></div>
<div className="text-2xl">{getCertificateIcon(cert.certificateType)}</div>
🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx at line 211, the template literal
used to combine the text size class and the certificate icon is incorrect for
displaying the emoji. Fix this by ensuring the emoji returned from
getCertificateIcon is properly included in the JSX, either by rendering it
directly inside the div or by correctly concatenating the className string
without using template literals for the emoji display.

Comment on lines +263 to +329
{showModal && selectedCertificate && (
<div className="fixed inset-0 z-50 flex items-center justify-center p-4">
<div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={() => setShowModal(false)}></div>
<motion.div
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
exit={{ opacity: 0, scale: 0.9 }}
className="bg-[rgba(30,30,40,0.98)] backdrop-blur-md border border-[rgba(180,120,255,0.18)] rounded-2xl p-8 max-w-2xl w-full max-h-[90vh] overflow-y-auto shadow-2xl"
>
<div className="flex items-center justify-between mb-6">
<h2 className="text-2xl font-bold text-white">Certificate Details</h2>
<button
onClick={() => setShowModal(false)}
className="text-white/60 hover:text-white text-2xl"
>
×
</button>
</div>

<div className="space-y-4 text-white">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="text-white/60 text-sm">Name</label>
<p className="font-semibold">{selectedCertificate.name}</p>
</div>
<div>
<label className="text-white/60 text-sm">Email</label>
<p className="font-semibold">{selectedCertificate.email}</p>
</div>
<div>
<label className="text-white/60 text-sm">Certificate Type</label>
<p className="font-semibold">{selectedCertificate.certificateType}</p>
</div>
<div>
<label className="text-white/60 text-sm">Unique ID</label>
<p className="font-mono font-semibold">{selectedCertificate.uniqueId}</p>
</div>
<div>
<label className="text-white/60 text-sm">Created Date</label>
<p className="font-semibold">{new Date(selectedCertificate.createdAt).toLocaleDateString()}</p>
</div>
<div>
<label className="text-white/60 text-sm">Status</label>
<p className="font-semibold text-green-400">✓ Valid</p>
</div>
</div>

<div className="flex gap-3 pt-4">
<button
onClick={() => handleDownload(selectedCertificate)}
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-green-500 to-green-600 rounded-lg text-white hover:scale-105 transition-transform"
>
<FaDownload />
Download Certificate
</button>
<button
onClick={() => handleShare(selectedCertificate)}
className="flex-1 flex items-center justify-center gap-2 px-4 py-3 bg-gradient-to-r from-blue-500 to-blue-600 rounded-lg text-white hover:scale-105 transition-transform"
>
<FaShare />
Share Certificate
</button>
</div>
</div>
</motion.div>
</div>
)}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Improve modal accessibility with focus trap and keyboard handling.

The modal lacks proper accessibility features like focus trapping and escape key handling.

 {showModal && selectedCertificate && (
-  <div className="fixed inset-0 z-50 flex items-center justify-center p-4">
+  <div 
+    className="fixed inset-0 z-50 flex items-center justify-center p-4"
+    role="dialog"
+    aria-modal="true"
+    aria-labelledby="modal-title"
+    onKeyDown={(e) => {
+      if (e.key === 'Escape') {
+        setShowModal(false);
+      }
+    }}
+  >
     <div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={() => setShowModal(false)}></div>
     <motion.div
       initial={{ opacity: 0, scale: 0.9 }}
       animate={{ opacity: 1, scale: 1 }}
       exit={{ opacity: 0, scale: 0.9 }}
       className="bg-[rgba(30,30,40,0.98)] backdrop-blur-md border border-[rgba(180,120,255,0.18)] rounded-2xl p-8 max-w-2xl w-full max-h-[90vh] overflow-y-auto shadow-2xl"
     >
       <div className="flex items-center justify-between mb-6">
-        <h2 className="text-2xl font-bold text-white">Certificate Details</h2>
+        <h2 id="modal-title" className="text-2xl font-bold text-white">Certificate Details</h2>

Consider using a library like react-focus-lock for proper focus management.

🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx around lines 263 to 329, the modal
component lacks accessibility features such as focus trapping and handling the
Escape key to close the modal. To fix this, integrate a focus management library
like react-focus-lock to trap keyboard focus within the modal while it is open,
and add an event listener to detect the Escape key press to close the modal by
calling setShowModal(false). This will improve keyboard navigation and overall
accessibility of the modal.

</div>
<div>
<label className="text-white/60 text-sm">Status</label>
<p className="font-semibold text-green-400">✓ Valid</p>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Don't hard-code certificate status.

The certificate status is hard-coded as "Valid" regardless of actual certificate state.

-<p className="font-semibold text-green-400">✓ Valid</p>
+<p className={`font-semibold ${selectedCertificate.isValid !== false ? 'text-green-400' : 'text-red-400'}`}>
+  {selectedCertificate.isValid !== false ? '✓ Valid' : '✗ Invalid'}
+</p>
🤖 Prompt for AI Agents
In Frontend/src/components/Certificate.jsx at line 306, the certificate status
is hard-coded as "Valid". Replace this static text with a dynamic expression
that reflects the actual certificate status from the component's state or props,
ensuring the displayed status updates correctly based on the certificate's real
validity.

@vercel
Copy link

vercel bot commented Aug 10, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
honor-box ✅ Ready (Inspect) Visit Preview 💬 Add feedback Aug 10, 2025 3:40am

@RamakrushnaBiswal
Copy link
Owner

@shanurajpoot001 its not woking like the img not showing after download
image

and the certificate should be show the perticular user
also create a another branch then give the PR , not from your main branch

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

Successfully merging this pull request may close these issues.

2 participants