diff --git a/public/popupcertificate.svg b/public/popupcertificate.svg new file mode 100644 index 0000000..86da62a --- /dev/null +++ b/public/popupcertificate.svg @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/app/(pages)/profile/page.jsx b/src/app/(pages)/profile/page.jsx index 32c27a7..7046d18 100644 --- a/src/app/(pages)/profile/page.jsx +++ b/src/app/(pages)/profile/page.jsx @@ -6,7 +6,6 @@ import { useSession, signOut } from 'next-auth/react'; import { FaPencilAlt } from 'react-icons/fa'; import styles from './page.module.css'; import defaultProfilePic from './profilepic.jpg'; -// Assuming you have a default profile pic import PdfForm from './PdfForm'; import certData from './certData'; import courseData from '../landing/courseData'; @@ -14,6 +13,46 @@ import ProgressBar from './progressBar'; import ProfilePopup from './profilePopup'; import PasswordPopup from './changePasswordPopup'; +function formatDate(dateString) { + const date = new Date(dateString); + const options = { year: 'numeric', month: 'long', day: 'numeric', timeZone: 'UTC' }; + return new Intl.DateTimeFormat('en-US', options).format(date); +} + +function CertificatePopup({ certificate, username, onClose, onDownload }) { + console.log(formatDate(certificate.date)); + return ( +
+
+
+
Certificate
+
x
+
+
+ Certificate Preview +
+
{username}
+
has successfully completed
+
{certificate.name}
+
Completed on + {formatDate(certificate.date)}
+
+
+ + +
+
+
+
+ ); +} + + function Profile() { const [isEditing, setIsEditing] = useState(false); const [profileImage, setProfileImage] = useState(defaultProfilePic); @@ -22,60 +61,45 @@ function Profile() { const [profilePopup, setProfilePopup] = useState(false); const [passwordPopup, setPasswordPopup] = useState(false); const [currentPage, setCurrentPage] = useState(0); + const [showPopup, setShowPopup] = useState(false); + const [selectedCertificate, setSelectedCertificate] = useState(null); const { data: session } = useSession(); - const getUserDetails = async (id) => { - if (!id) return; - const response = await fetch('/api/users/me', { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ id }), - }); - - const data = await response.json(); - // console.log("here", data); - setData(data.user); - setEditedName(data.user.userName); - }; - useEffect(() => { - console.log('session', session); - if (session) getUserDetails(session.user.id); + if (session) { + const getUserDetails = async () => { + const response = await fetch('/api/users/me', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ id: session.user.id }), + }); + const data = await response.json(); + if (data.user) { + setData(data.user); + setEditedName(data.user.userName); + } + }; + getUserDetails(); + } }, [session]); - - const updateUserData = (data) => { - // update the user data in the database, make sure only the first user is updated. - async function updateUserDataInDB() { - // eslint-disable-next-line no-console - console.log('data', data); - + + const updateUserData = (newData) => { + const updateUserDataInDB = async () => { const response = await fetch('/api/users/me/change-name', { method: 'PATCH', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ userName: data.userName, userId: data.id }), + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ userName: newData.userName, userId: newData.id }), }); const res = await response.json(); - // eslint-disable-next-line no-console - console.log('res', res); - - if (res.error) { - // eslint-disable-next-line no-alert + if (!res.error) { + setData(newData); + localStorage.setItem('userData', JSON.stringify(newData)); + } else { alert(res.error); - throw new Error(res.error); } - - // eslint-disable-next-line no-console - console.log('Update success', response.data); - } + }; updateUserDataInDB(); - - // update the user data in the local storage - localStorage.setItem('userData', JSON.stringify(data)); }; const handleNameClick = () => { @@ -122,6 +146,29 @@ function Profile() { setCurrentPage(page); }; + const handleCertificateClick = (event, certificate) => { + event.preventDefault(); + event.stopPropagation(); + setSelectedCertificate(certificate); + setShowPopup(true); + }; + + const handleDownloadPdf = (certificate) => { + const pdfUrl = `/certificate.pdf`; + fetch(pdfUrl) + .then(response => response.blob()) + .then(blob => { + const url = window.URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = `${certificate.name}.pdf`; + document.body.appendChild(a); + a.click(); + a.remove(); + window.URL.revokeObjectURL(url); + }) + .catch(e => console.error('Download error:', e)); + }; return ( userData ? ( @@ -131,6 +178,15 @@ function Profile() { {profilePopup && } {passwordPopup && } + {showPopup && ( + setShowPopup(false)} + onDownload={handleDownloadPdf} + /> + )} +
{displayedCertificates.map((certificate, index) => (
handleCertificateClick(e, certificate)} + className={styles.certificateItem} + style={{ + backgroundImage: 'url("/certificate.jpg")', + borderRadius: '10px', + backgroundSize: 'cover', }} > {userData && ( diff --git a/src/app/(pages)/profile/page.module.css b/src/app/(pages)/profile/page.module.css index 53a4d2f..2483b36 100644 --- a/src/app/(pages)/profile/page.module.css +++ b/src/app/(pages)/profile/page.module.css @@ -90,38 +90,58 @@ padding-bottom: 10px; display: flex; justify-content: center; align-items: center; + z-index: 1000; } .popUp{ - position: absolute; - background-color: white; - border: 1px solid black; - padding: 50px 50px; - border-radius: 10px; + position: absolute; + background-color: #FFFFFF; + border: 1px solid black; + padding: 20px; + border-radius: 10px; + width: 65%; + max-height: 100vh; + box-shadow: 0 4px 6px rgba(0,0,0,0.1); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + overflow: hidden; + z-index: 1001; + } + +.popUpContent{ + background-size: cover; + border: none; + width: 70%; + height: 300px; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + text-align: center; + padding: 20px; } .popTop{ display: flex; justify-content: space-between; - border-bottom: 1px solid gray; - margin-bottom: 10px; + align-items: center; + width: 100%; + padding: 0 10px; + border-bottom: none; } .popTitle{ - font-size: 20px; - font-weight: 550; + font-size: 19px; padding-bottom: 10px; + color: #333; + padding-left: 5px; } -.popSubTitle{ - font-size: 20px; - font-weight: 550; - padding: 20px 0px; -} - -.popText{ - font-size: 18px; - color: gray; +.completionDate { + font-weight: bold; + color: #333; } .popPicAll{ @@ -131,7 +151,7 @@ padding-bottom: 10px; } .popPic{ - width: 100px; /* Adjust the width dynamically */ + width: 100px; height: 100px; border-radius: 50px; background-size: cover; @@ -145,23 +165,40 @@ padding-bottom: 10px; } .popBottom{ - display: flex; - justify-content: right; -} + display: flex; + justify-content: flex-end; + padding-top: 20px; + } .popButton{ - font-size: 18px; - border: 1px solid black; - border-radius: 10px; - padding: 2px 10px; + font-size: 13px; + border: none; + border-radius: 15px; + padding: 7px 20px; margin: 5px; cursor: pointer; + background-color: #4CAF50; + color: white; +} + +.cancelButton{ + background-color: #FFFFFF; + color: #333; + border: 1px solid #ccc; + +} + +.downloadButton{ + background-color: #4CAF50; + color: white; + margin-right: -100px; } .popClose{ cursor: pointer; font-size: 20px; font-weight: 500; + color: #aaa; } /* account section */ @@ -219,6 +256,51 @@ padding-bottom: 10px; gap: 5px; } + .popMiddle { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 0px; + } + + .popupCompletion, .popupBold, .popupCertificateName, .popupCertificateInfo, .popupCertificateCourseName { + text-align: center; + width: 100%; + position: absolute; + z-index: 1; +} + + .popupCertificateName { + font-size: 24px; + color: black; + margin-top: -520px; + font-weight: semi-bold; + } + + .popupCertificateInfo { + font-size: 23px; + color: black; + margin-top: -420px; + } + + .popupCompletion { + font-size: 18px; + color: #333; + margin-top: -210px; + } + + .popupBold { + font-weight: bold; + } + + .popupCertificateCourseName { + font-size: 23px; + font-weight: 500; + color: #333; + margin-top: -360px; + } + .paginationDots{ text-align: right; color: gray;