Merge pull request #234 from nathen418/add_certifications_section

Add a certificate section
This commit is contained in:
Ariful Alam 2022-12-09 20:17:28 +06:00 committed by GitHub
commit d1b2404e97
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 0 deletions

View File

@ -68,6 +68,7 @@
✓ [Social Links](#social-links)
✓ [Skill Section](#skills)
✓ [Experience Section](#experience)
✓ [Certifications Section](#certifications)
✓ [Education Section](#education)
✓ [Projects Section](#projects)
✓ [Blog Posts Section](#blog-posts)
@ -243,6 +244,14 @@ const config = {
companyLink: 'https://example.com',
},
],
certifications: [
{
body: 'Certification Body Name',
name: 'Sample Certification',
year: 'March 2022',
certLink: 'https://example.com'
},
],
education: [
{
institution: 'Institution Name',
@ -482,6 +491,27 @@ module.exports = {
Empty array will hide the experience section.
### Certifications
Provide your industry certifications in `certifications`.
```js
// gitprofile.config.js
module.exports = {
// ...
certifications: [
{
body: 'Certification Body Name',
name: 'My Sample Certification',
year: 'March 2022',
certLink: 'https://example.com'
},
],
};
```
Empty array will hide the certifications section.
### Education
Provide your education history in `education`.

View File

@ -59,6 +59,14 @@ const config = {
companyLink: 'https://example.com',
},
],
certifications: [
{
body: 'Certification Body Name',
name: 'My Sample Certification',
year: 'March 2022',
certLink: 'https://example.com'
},
],
education: [
{
institution: 'Institution Name',

View File

@ -7,6 +7,7 @@ import AvatarCard from './avatar-card';
import Details from './details';
import Skill from './skill';
import Experience from './experience';
import Certifications from './certifications';
import Education from './education';
import Project from './project';
import Blog from './blog';
@ -183,6 +184,10 @@ const GitProfile = ({ config }) => {
loading={loading}
experiences={sanitizedConfig.experiences}
/>
<Certifications
loading={loading}
certifications={sanitizedConfig.certifications}
/>
<Education
loading={loading}
education={sanitizedConfig.education}
@ -272,6 +277,13 @@ GitProfile.propTypes = {
to: PropTypes.string,
})
),
certifications: PropTypes.arrayOf(
PropTypes.shape({
body: PropTypes.string,
name: PropTypes.string,
year: PropTypes.string,
})
),
education: PropTypes.arrayOf(
PropTypes.shape({
institution: PropTypes.string,

View File

@ -0,0 +1,101 @@
import { skeleton } from '../../helpers/utils';
import { Fragment } from 'react';
import PropTypes from 'prop-types';
const ListItem = ({ year, name, body, certLink }) => (
<li className="mb-5 ml-4">
<div
className="absolute w-2 h-2 bg-base-300 rounded-full border border-base-300 mt-1.5"
style={{ left: '-4.5px' }}
></div>
<div className="my-0.5 text-xs">{year}</div>
<div className="font-semibold">
<a href={certLink} target="_blank" rel="noreferrer">
{name}
</a>
</div>
<h3 className="mb-4 font-normal">{body}</h3>
</li>
);
const Certifications = ({ certifications, loading }) => {
const renderSkeleton = () => {
let array = [];
for (let index = 0; index < 2; index++) {
array.push(
<ListItem
key={index}
year={skeleton({
width: 'w-5/12',
height: 'h-4',
})}
name={skeleton({
width: 'w-6/12',
height: 'h-4',
className: 'my-1.5',
})}
body={skeleton({ width: 'w-6/12', height: 'h-3' })}
/>
);
}
return array;
};
return (
<>
{certifications?.length !== 0 && (
<div className="card shadow-lg compact bg-base-100">
<div className="card-body">
<div className="mx-3">
<h5 className="card-title">
{loading ? (
skeleton({ width: 'w-32', height: 'h-8' })
) : (
<span className="text-base-content opacity-70">
Certifications
</span>
)}
</h5>
</div>
<div className="text-base-content text-opacity-60">
<ol className="relative border-l border-base-300 border-opacity-30 my-2 mx-4">
{loading ? (
renderSkeleton()
) : (
<Fragment>
{certifications.map((certification, index) => (
<ListItem
key={index}
year={`${certification.year}`}
name={certification.name}
body={certification.body}
certLink={
certification.certLink ? certification.certLink : null
}
/>
))}
</Fragment>
)}
</ol>
</div>
</div>
</div>
)}
</>
);
};
ListItem.propTypes = {
year: PropTypes.node,
name: PropTypes.node,
body: PropTypes.node,
certLink: PropTypes.string,
};
Certifications.propTypes = {
certifications: PropTypes.array.isRequired,
loading: PropTypes.bool.isRequired,
};
export default Certifications;

View File

@ -163,6 +163,7 @@ export const sanitizeConfig = (config) => {
},
skills: config?.skills || [],
experiences: config?.experiences || [],
certifications: config?.certifications || [],
education: config?.education || [],
blog: {
source: config?.blog?.source,

11
types/index.d.ts vendored
View File

@ -214,6 +214,12 @@ export interface Experience {
to?: string;
companyLink?: string;
}
export interface Certifications {
body?: string;
name?: string;
year?: string;
certLink?: string;
}
export interface Education {
institution?: string;
@ -252,6 +258,11 @@ export interface Config {
*/
experiences?: Array<Experience>;
/**
* Certifications list
*/
certifications?: Array<Certifications>;
/**
* Education list
*/