Add markdown support into descriptions for adding links
This commit is contained in:
parent
0d1e962999
commit
be6d74d24a
894
package-lock.json
generated
894
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -22,6 +22,7 @@
|
|||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
"react-bootstrap": "^2.7.4",
|
"react-bootstrap": "^2.7.4",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
|
"react-markdown": "^8.0.7",
|
||||||
"typescript": "5.0.4"
|
"typescript": "5.0.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ export const personalData: PersonalData = {
|
|||||||
{icon: 'telephone', text: '+420 111 222 333'},
|
{icon: 'telephone', text: '+420 111 222 333'},
|
||||||
{icon: 'geo-alt', text: 'Brno, Czechia'}
|
{icon: 'geo-alt', text: 'Brno, Czechia'}
|
||||||
],
|
],
|
||||||
|
|
||||||
jobs: {
|
jobs: {
|
||||||
current: {
|
current: {
|
||||||
position: 'Senior Software Development Manager (UI Platform)',
|
position: 'Senior Software Development Manager (UI Platform)',
|
||||||
@ -57,6 +58,16 @@ export const personalData: PersonalData = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
|
projects: {
|
||||||
|
current: {
|
||||||
|
position: `Personal projects`,
|
||||||
|
description: `Various hardware and software projects. Usually open sourced and published on [projects.dejvino.com](https://projects.dejvino.com) .
|
||||||
|
These include video games, utilities, 3D models, devices with embedded microcontrollers etc.`,
|
||||||
|
tags: ['Java', 'Python', 'C/C++', 'Embedded devices', 'OpenSCAD', 'TypeScript', 'Linux', 'Git', 'Self-hosting']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
education: {
|
education: {
|
||||||
previous: [
|
previous: [
|
||||||
{
|
{
|
||||||
@ -73,11 +84,12 @@ export const personalData: PersonalData = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
skills: {
|
skills: {
|
||||||
primary: ['Java', 'TypeScript', 'JavaScript'],
|
primary: ['Java', 'TypeScript', 'JavaScript', 'Engineering leadership', 'Linux'],
|
||||||
secondary: ['Kotlin', 'Go'],
|
secondary: ['SQL', 'Kotlin', 'Go', 'C/C++', 'NodeJs', 'Git', 'Preact', 'Embedded devices'],
|
||||||
languages: ['Czech (native)', 'English (proficient)', 'German (elementary)'],
|
languages: ['Czech (native)', 'English (proficient)', 'German (elementary)'],
|
||||||
others: ['Driver\'s license (B)']
|
others: ['Driver\'s license (B)']
|
||||||
},
|
},
|
||||||
interests: ['Guitars and Heavy Metal', 'Mazda MX-5', 'DIY electronics'],
|
interests: ['Guitars', 'Heavy Metal', 'Mazda MX-5', 'DIY electronics', 'Linux', 'Open source'],
|
||||||
};
|
};
|
||||||
|
@ -5,8 +5,8 @@ export type Contact = {
|
|||||||
|
|
||||||
export type Job = {
|
export type Job = {
|
||||||
position: string,
|
position: string,
|
||||||
company: string,
|
company?: string,
|
||||||
timerange: string,
|
timerange?: string,
|
||||||
description: string,
|
description: string,
|
||||||
tags?: string[],
|
tags?: string[],
|
||||||
}
|
}
|
||||||
@ -18,6 +18,8 @@ export type Jobs = {
|
|||||||
|
|
||||||
export type Education = Jobs;
|
export type Education = Jobs;
|
||||||
|
|
||||||
|
export type Projects = Jobs;
|
||||||
|
|
||||||
export type Skills = {
|
export type Skills = {
|
||||||
primary: string[],
|
primary: string[],
|
||||||
secondary?: string[],
|
secondary?: string[],
|
||||||
@ -31,6 +33,7 @@ export type PersonalData = {
|
|||||||
brief: string,
|
brief: string,
|
||||||
contacts: Contact[],
|
contacts: Contact[],
|
||||||
jobs: Jobs,
|
jobs: Jobs,
|
||||||
|
projects?: Projects,
|
||||||
education?: Education,
|
education?: Education,
|
||||||
skills: Skills,
|
skills: Skills,
|
||||||
interests: string[]
|
interests: string[]
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext } from 'react';
|
||||||
import Container from 'react-bootstrap/Container';
|
import Container from 'react-bootstrap/Container';
|
||||||
import Image from 'react-bootstrap/Image'
|
|
||||||
import { usePersonContext } from '../hooks/PersonContext';
|
import { usePersonContext } from '../hooks/PersonContext';
|
||||||
import { Col, Row } from 'react-bootstrap';
|
import md from './Markdown';
|
||||||
|
|
||||||
export default function AboutBrief() {
|
export default function AboutBrief() {
|
||||||
const person = usePersonContext()
|
const person = usePersonContext()
|
||||||
return (
|
return (
|
||||||
<Container className='about-brief' fluid>
|
<Container className='about-brief' fluid>
|
||||||
<h1>{person.name}</h1>
|
<h1>{person.name}</h1>
|
||||||
<p className='brief'>{person.brief}</p>
|
<p className='brief'>{md(person.brief)}</p>
|
||||||
</Container>
|
</Container>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import { usePersonContext } from '../hooks/PersonContext';
|
import { usePersonContext } from '../hooks/PersonContext';
|
||||||
import JobHistory from './job/JobsHistory';
|
import JobHistory from './job/JobsHistory';
|
||||||
|
|
||||||
export default function WorkExperience() {
|
export default function Education() {
|
||||||
const person = usePersonContext()
|
const person = usePersonContext()
|
||||||
|
|
||||||
return person.education ? (
|
return person.education ? (
|
||||||
|
5
src/app/components/Markdown.tsx
Normal file
5
src/app/components/Markdown.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import ReactMarkdown from "react-markdown";
|
||||||
|
|
||||||
|
export default function md(text: string) {
|
||||||
|
return <ReactMarkdown>{text}</ReactMarkdown>
|
||||||
|
}
|
16
src/app/components/Projects.tsx
Normal file
16
src/app/components/Projects.tsx
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { usePersonContext } from '../hooks/PersonContext';
|
||||||
|
import JobHistory from './job/JobsHistory';
|
||||||
|
|
||||||
|
export default function Projects() {
|
||||||
|
const person = usePersonContext()
|
||||||
|
|
||||||
|
return person.projects ? (
|
||||||
|
<JobHistory
|
||||||
|
jobs={person.projects}
|
||||||
|
heading='Projects'
|
||||||
|
currentHeading='Currently active'
|
||||||
|
/>
|
||||||
|
) : <></>
|
||||||
|
}
|
@ -3,14 +3,11 @@ import Card from 'react-bootstrap/Card';
|
|||||||
import { useAutoFocus } from '../../hooks/FocusedElement';
|
import { useAutoFocus } from '../../hooks/FocusedElement';
|
||||||
import { Placeholder } from 'react-bootstrap';
|
import { Placeholder } from 'react-bootstrap';
|
||||||
import JobTags from './JobTags';
|
import JobTags from './JobTags';
|
||||||
|
import { Job } from '@/PersonalDataTypes';
|
||||||
|
import md from '../Markdown';
|
||||||
|
|
||||||
export type Props = {
|
export type Props = Job & {
|
||||||
heading?: string,
|
heading?: string
|
||||||
position: string,
|
|
||||||
timerange: string,
|
|
||||||
company: string,
|
|
||||||
description: string,
|
|
||||||
tags?: string[]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export function JobCardPlaceholder() {
|
export function JobCardPlaceholder() {
|
||||||
@ -37,9 +34,11 @@ export default function JobCard(props: Props) {
|
|||||||
<Card.Body>
|
<Card.Body>
|
||||||
<Card.Title>{props.position}</Card.Title>
|
<Card.Title>{props.position}</Card.Title>
|
||||||
<Card.Subtitle>
|
<Card.Subtitle>
|
||||||
<span className='company-name'>{props.company}</span>, <span className='timerange'>{props.timerange}</span>
|
{props.company && <span className='company-name'>{props.company}</span>}
|
||||||
|
{props.company && props.timerange && <span>, </span>}
|
||||||
|
{props.timerange && <span className='timerange'>{props.timerange}</span>}
|
||||||
</Card.Subtitle>
|
</Card.Subtitle>
|
||||||
<Card.Text className='multiline'>{props.description}</Card.Text>
|
<Card.Text className='multiline'>{md(props.description)}</Card.Text>
|
||||||
{props.tags && <JobTags tags={props.tags} />}
|
{props.tags && <JobTags tags={props.tags} />}
|
||||||
</Card.Body>
|
</Card.Body>
|
||||||
</Card>
|
</Card>
|
||||||
|
@ -4,6 +4,7 @@ import { Job } from '@/PersonalDataTypes';
|
|||||||
import { Accordion, Row } from 'react-bootstrap';
|
import { Accordion, Row } from 'react-bootstrap';
|
||||||
import { JobListProps } from './types';
|
import { JobListProps } from './types';
|
||||||
import JobTags from './JobTags';
|
import JobTags from './JobTags';
|
||||||
|
import md from '../Markdown';
|
||||||
|
|
||||||
|
|
||||||
export type Props = {
|
export type Props = {
|
||||||
@ -23,7 +24,7 @@ export default function JobsAccordion(props: JobListProps) {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div><strong>{job.position}</strong></div>
|
<div><strong>{job.position}</strong></div>
|
||||||
<div>{job.company}, {job.timerange}</div>
|
<div>{[job.company, job.timerange].filter(x => x).join(', ')}</div>
|
||||||
{heading && (<div>({heading})</div>)}
|
{heading && (<div>({heading})</div>)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -34,7 +35,7 @@ export default function JobsAccordion(props: JobListProps) {
|
|||||||
<Accordion.Item eventKey="current">
|
<Accordion.Item eventKey="current">
|
||||||
<Accordion.Header><JobTitle heading={config.currentHeading} job={jobs.current} /> </Accordion.Header>
|
<Accordion.Header><JobTitle heading={config.currentHeading} job={jobs.current} /> </Accordion.Header>
|
||||||
<Accordion.Body>
|
<Accordion.Body>
|
||||||
{jobs.current.description}
|
{md(jobs.current.description)}
|
||||||
{jobs.current.tags && <JobTags tags={jobs.current.tags} />}
|
{jobs.current.tags && <JobTags tags={jobs.current.tags} />}
|
||||||
</Accordion.Body>
|
</Accordion.Body>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
@ -43,7 +44,7 @@ export default function JobsAccordion(props: JobListProps) {
|
|||||||
<Accordion.Item eventKey={`previous-${index}`} key={index}>
|
<Accordion.Item eventKey={`previous-${index}`} key={index}>
|
||||||
<Accordion.Header><JobTitle job={job} /></Accordion.Header>
|
<Accordion.Header><JobTitle job={job} /></Accordion.Header>
|
||||||
<Accordion.Body className='multiline'>
|
<Accordion.Body className='multiline'>
|
||||||
{job.description}
|
{md(job.description)}
|
||||||
{job.tags && <JobTags tags={job.tags} />}
|
{job.tags && <JobTags tags={job.tags} />}
|
||||||
</Accordion.Body>
|
</Accordion.Body>
|
||||||
</Accordion.Item>
|
</Accordion.Item>
|
||||||
|
@ -65,7 +65,7 @@ body {
|
|||||||
margin: 0.75em;
|
margin: 0.75em;
|
||||||
}
|
}
|
||||||
.accordion-button.collapsed {
|
.accordion-button.collapsed {
|
||||||
background-color: lavender;
|
background-color: #eff2ff;
|
||||||
}
|
}
|
||||||
.accordion {
|
.accordion {
|
||||||
margin: 1rem;
|
margin: 1rem;
|
||||||
|
@ -9,7 +9,7 @@ import Education from './components/Education';
|
|||||||
import { Col, Row } from 'react-bootstrap';
|
import { Col, Row } from 'react-bootstrap';
|
||||||
import Footer from './components/Footer';
|
import Footer from './components/Footer';
|
||||||
import Photo from './components/Photo';
|
import Photo from './components/Photo';
|
||||||
import useSize from './hooks/Size';
|
import Projects from './components/Projects';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
@ -27,6 +27,7 @@ export default function Home() {
|
|||||||
<Row>
|
<Row>
|
||||||
<Col xs={12} xl={7}>
|
<Col xs={12} xl={7}>
|
||||||
<Row><WorkExperience /></Row>
|
<Row><WorkExperience /></Row>
|
||||||
|
<Row><Projects /></Row>
|
||||||
<Row><Education /></Row>
|
<Row><Education /></Row>
|
||||||
</Col>
|
</Col>
|
||||||
<Col>
|
<Col>
|
||||||
|
Loading…
Reference in New Issue
Block a user