This commit is contained in:
parent
d7dcbb0ea8
commit
6ae1cf268d
71
src/CV.tsx
71
src/CV.tsx
@ -1,4 +1,4 @@
|
|||||||
import React, {useEffect} from 'react';
|
import React, {useEffect, useState} from 'react';
|
||||||
import Header from './Components/Header';
|
import Header from './Components/Header';
|
||||||
import './Assets/scss/CV.scss'
|
import './Assets/scss/CV.scss'
|
||||||
import Jobs from './Components/Jobs';
|
import Jobs from './Components/Jobs';
|
||||||
@ -14,58 +14,53 @@ import {SideProjectCats} from './Model/side-project';
|
|||||||
import {JobAtCompany} from './Model/job-at-company';
|
import {JobAtCompany} from './Model/job-at-company';
|
||||||
import {Interest} from './Model/interests';
|
import {Interest} from './Model/interests';
|
||||||
import {Profile} from './Model/profile';
|
import {Profile} from './Model/profile';
|
||||||
|
import { Me } from './Model/me';
|
||||||
|
|
||||||
function CV() {
|
function CV() {
|
||||||
const tags: Tag[] = []
|
|
||||||
|
|
||||||
const langs: Lang[] = []
|
const [error, setError] = useState(null);
|
||||||
|
const [isLoaded, setIsLoaded] = useState(false);
|
||||||
const ed: EducationYear[] = []
|
const [cv, setCV] = useState<Me>(new Me());
|
||||||
|
|
||||||
const projs: SideProjectCats[] = []
|
|
||||||
|
|
||||||
const jobs: JobAtCompany[] = []
|
|
||||||
|
|
||||||
const interests: Interest[] = []
|
|
||||||
|
|
||||||
const profile: Profile = {
|
|
||||||
"name": "",
|
|
||||||
"title": "",
|
|
||||||
"quote": "",
|
|
||||||
"picture": ""
|
|
||||||
}
|
|
||||||
|
|
||||||
document.title = profile.name;
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let link = document.querySelector("link[rel~='icon']");
|
fetch("http://localhost:7070/api/me")
|
||||||
if (!link) {
|
.then(res => res.json())
|
||||||
link = document.createElement('link');
|
.then(
|
||||||
// @ts-ignore
|
(result: Me) => {
|
||||||
link.rel = 'icon';
|
setIsLoaded(true);
|
||||||
document.getElementsByTagName('head')[0].appendChild(link);
|
setCV(result);
|
||||||
|
document.title = result.profile.name;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
setIsLoaded(true);
|
||||||
|
setError(error);
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
)
|
||||||
link.href = profile.picture
|
}, [])
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
if (error) {
|
||||||
<div className="CV">
|
return <div>Error: {error}</div>;
|
||||||
<Header tags={tags} profile={profile}/>
|
} else if (!isLoaded) {
|
||||||
|
return <div>Loading...</div>;
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return (<div className="CV">
|
||||||
|
<Header tags={cv.tags.filter(t => t.workThing)} profile={cv.profile}/>
|
||||||
<div className="card flex divide-x divide-gray-600">
|
<div className="card flex divide-x divide-gray-600">
|
||||||
<div className="basis-3/4 pr-2 divide-y divide-gray-400 details">
|
<div className="basis-3/4 pr-2 divide-y divide-gray-400 details">
|
||||||
<Jobs jobs={jobs}/>
|
<Jobs jobs={cv.jobs}/>
|
||||||
<Education education={ed}/>
|
<Education education={cv.educationYears}/>
|
||||||
<SideProjects projs={projs}/>
|
<SideProjects projs={cv.sideProjects}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="basis-1/4 pl-2 divide-y divide-gray-400 details">
|
<div className="basis-1/4 pl-2 divide-y divide-gray-400 details">
|
||||||
<Skills tags={tags}/>
|
<Skills tags={cv.tags}/>
|
||||||
<Languages langs={langs}/>
|
<Languages langs={cv.languages}/>
|
||||||
<Interests interests={interests}/>
|
<Interests interests={cv.interests}/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default CV;
|
export default CV;
|
||||||
|
@ -8,7 +8,7 @@ function Job(props: ComponentProps<any>) {
|
|||||||
</div>
|
</div>
|
||||||
<h5>{props.company}</h5>
|
<h5>{props.company}</h5>
|
||||||
<ul>
|
<ul>
|
||||||
{props.tasks.map((task: string) => <li key={task}>{task}</li>)}
|
{props.tasks.split("|").map((task: string) => <li key={task}>{task}</li>)}
|
||||||
</ul>
|
</ul>
|
||||||
</div>);
|
</div>);
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import React, {ComponentProps} from 'react';
|
import React, {ComponentProps} from 'react';
|
||||||
import {BeakerIcon} from '@heroicons/react/24/outline';
|
import {BeakerIcon} from '@heroicons/react/24/outline';
|
||||||
import {SideProjectCats} from '../Model/side-project';
|
import {SideProject} from '../Model/side-project';
|
||||||
|
import {each, keys, map} from 'lodash';
|
||||||
|
|
||||||
function SideProjects(props: ComponentProps<any>) {
|
function SideProjects(props: ComponentProps<any>) {
|
||||||
return (<div className="prose">
|
return (<div className="prose">
|
||||||
<h3><BeakerIcon className="icon"/> Projets personnels</h3>
|
<h3><BeakerIcon className="icon"/> Projets personnels</h3>
|
||||||
{props.projs.map((proj: SideProjectCats) => {
|
{Object.entries(props.projs).map(projectsOfCat => {
|
||||||
return (<div key={proj.category}>
|
const cat = projectsOfCat[0];
|
||||||
<h4>{proj.category}</h4>
|
const projs = projectsOfCat[1] as SideProject[];
|
||||||
|
return (<div key={cat}>
|
||||||
|
<h4>{cat}</h4>
|
||||||
<ul>
|
<ul>
|
||||||
{proj.projects.map(p => {
|
{projs.map((p: SideProject) => {
|
||||||
return (<li key={p.description}>
|
return (<li key={p.description}>
|
||||||
{p.title ? <div><a href={p.url}>{p.title}</a> {p.description}</div> : <div>{p.description}</div>}
|
{p.title ? <div><a href={p.url}>{p.title}</a> {p.description}</div> : <div>{p.description}</div>}
|
||||||
</li>)
|
</li>)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import React, {ComponentProps} from 'react';
|
import React, {ComponentProps} from 'react';
|
||||||
import {CalendarDaysIcon, CheckBadgeIcon, LanguageIcon} from '@heroicons/react/24/outline';
|
import {CalendarDaysIcon, CheckBadgeIcon, LanguageIcon} from '@heroicons/react/24/outline';
|
||||||
import {getTagColor, Tag, TagCategory} from '../Model/tag';
|
import {getTagColor, getTagTitle, Tag, TagCategory} from '../Model/tag';
|
||||||
import {forIn, groupBy, map} from 'lodash';
|
import {forIn, groupBy, map} from 'lodash';
|
||||||
|
|
||||||
function Skills(props: ComponentProps<any>) {
|
function Skills(props: ComponentProps<any>) {
|
||||||
@ -10,7 +10,7 @@ function Skills(props: ComponentProps<any>) {
|
|||||||
<div className="flex flex-wrap justify-between">
|
<div className="flex flex-wrap justify-between">
|
||||||
{map(tagsByCat, (tags, cat) => {
|
{map(tagsByCat, (tags, cat) => {
|
||||||
return (<div key={cat}>
|
return (<div key={cat}>
|
||||||
<h4 className="m-0 mb-1.5">{cat}</h4>
|
<h4 className="m-0 mb-1.5">{getTagTitle(cat)}</h4>
|
||||||
<div>
|
<div>
|
||||||
{tags.map((t: Tag) => <button key={t.name} className={"tag " + getTagColor(t)}>{t.name}</button>)}
|
{tags.map((t: Tag) => <button key={t.name} className={"tag " + getTagColor(t)}>{t.name}</button>)}
|
||||||
</div>
|
</div>
|
||||||
|
17
src/Model/me.ts
Normal file
17
src/Model/me.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import {EducationYear} from './education';
|
||||||
|
import {SideProject} from './side-project';
|
||||||
|
import {Interest} from './interests';
|
||||||
|
import {Profile} from './profile';
|
||||||
|
import {Tag} from './tag';
|
||||||
|
import {Lang} from './lang';
|
||||||
|
import {JobAtCompany} from './job-at-company';
|
||||||
|
|
||||||
|
export class Me {
|
||||||
|
profile!: Profile
|
||||||
|
interests!: Interest[]
|
||||||
|
jobs!: JobAtCompany[]
|
||||||
|
sideProjects!: Map<string, SideProject[]>
|
||||||
|
educationYears!: EducationYear[]
|
||||||
|
languages!: Lang[]
|
||||||
|
tags!: Tag[]
|
||||||
|
}
|
@ -2,6 +2,7 @@ export class SideProject {
|
|||||||
title?: string
|
title?: string
|
||||||
url?: string
|
url?: string
|
||||||
description!: string
|
description!: string
|
||||||
|
category!: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SideProjectCats {
|
export class SideProjectCats {
|
||||||
|
@ -13,12 +13,27 @@ export function getTagColor(t: Tag) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function getTagTitle(cat: string) {
|
||||||
|
switch (cat) {
|
||||||
|
case TagCategory.FRONT:
|
||||||
|
return 'Developpement Front'
|
||||||
|
case TagCategory.BACK:
|
||||||
|
return 'Developpement Back'
|
||||||
|
case TagCategory.MOBILE:
|
||||||
|
return 'Developpement Mobile'
|
||||||
|
case TagCategory.DB:
|
||||||
|
return 'Bases de données'
|
||||||
|
case TagCategory.OTHER:
|
||||||
|
return 'Autre'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export enum TagCategory {
|
export enum TagCategory {
|
||||||
FRONT = 'Developpement Front',
|
FRONT = 'FRONT',
|
||||||
BACK = 'Developpement Back',
|
BACK = 'BACK',
|
||||||
MOBILE = 'Developpement Mobile',
|
MOBILE = 'MOBILE',
|
||||||
DB = 'Bases de données',
|
DB = 'DB',
|
||||||
OTHER = 'Autre'
|
OTHER = 'OTHER'
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Tag {
|
export class Tag {
|
||||||
|
Loading…
Reference in New Issue
Block a user