mirror of
https://github.com/AmruthPillai/Reactive-Resume.git
synced 2025-11-10 04:22:27 +10:00
Compare commits
18 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8864243558 | |||
| 37aab7a16f | |||
| 86e1bdf7ea | |||
| 4547fd213d | |||
| 5aacec40cc | |||
| 1df78100ca | |||
| 9cd36fcb9b | |||
| 24b32eb917 | |||
| dec0e41fec | |||
| 42700ad2b2 | |||
| df51d79f6b | |||
| be1673a6a7 | |||
| 648f182e76 | |||
| 3aa56f0886 | |||
| b795534da7 | |||
| c67e2ac9f8 | |||
| ac569324cf | |||
| 357d197bb3 |
@ -4,13 +4,15 @@ PUBLIC_URL=http://localhost
|
||||
PUBLIC_SERVER_URL=http://localhost/api
|
||||
PUBLIC_GOOGLE_CLIENT_ID=
|
||||
|
||||
# Database
|
||||
POSTGRES_DB=postgres
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=postgres
|
||||
|
||||
# Server
|
||||
SECRET_KEY=
|
||||
POSTGRES_HOST=postgres
|
||||
POSTGRES_PORT=5432
|
||||
POSTGRES_USER=postgres
|
||||
POSTGRES_PASSWORD=postgres
|
||||
POSTGRES_DATABASE=postgres
|
||||
POSTGRES_SSL_CERT=
|
||||
JWT_SECRET=
|
||||
JWT_EXPIRY_TIME=604800
|
||||
|
||||
28
.github/workflows/docker-build-push.yml
vendored
28
.github/workflows/docker-build-push.yml
vendored
@ -17,6 +17,12 @@ jobs:
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to Docker
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
@ -29,6 +35,7 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
file: client/Dockerfile
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:client-latest
|
||||
amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
|
||||
@ -45,6 +52,12 @@ jobs:
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to Docker
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
@ -57,6 +70,7 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
file: server/Dockerfile
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: |
|
||||
amruthpillai/reactive-resume:server-latest
|
||||
amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}
|
||||
@ -73,6 +87,12 @@ jobs:
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
@ -86,6 +106,7 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
file: client/Dockerfile
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: |
|
||||
ghcr.io/amruthpillai/reactive-resume:client-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:client-${{ steps.version.outputs.tag }}
|
||||
@ -102,6 +123,12 @@ jobs:
|
||||
name: Get Version
|
||||
run: echo ::set-output name=tag::${GITHUB_REF#refs/*/}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1.2.0
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1.6.0
|
||||
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1.14.1
|
||||
with:
|
||||
@ -115,6 +142,7 @@ jobs:
|
||||
context: .
|
||||
push: true
|
||||
file: server/Dockerfile
|
||||
platforms: linux/amd64,linux/arm/v7,linux/arm64
|
||||
tags: |
|
||||
ghcr.io/amruthpillai/reactive-resume:server-latest
|
||||
ghcr.io/amruthpillai/reactive-resume:server-${{ steps.version.outputs.tag }}
|
||||
|
||||
@ -2,6 +2,13 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [3.3.0](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.11...v3.3.0) (2022-04-08)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **upgrade:** changes to code to support new template ([1df7810](https://github.com/AmruthPillai/Reactive-Resume/commit/1df78100ca0667ce9b7834cf2c25384eb21c67c2))
|
||||
|
||||
### [3.2.11](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.10...v3.2.11) (2022-03-28)
|
||||
|
||||
### [3.2.10](https://github.com/AmruthPillai/Reactive-Resume/compare/v3.2.9...v3.2.10) (2022-03-24)
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
plugins {
|
||||
id 'com.android.application' version '7.1.2' apply false
|
||||
id 'com.android.library' version '7.1.2' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.10' apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.6.20' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
|
||||
@ -9,15 +9,15 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@beam-australia/react-env": "^3.1.1",
|
||||
"@emotion/css": "^11.7.1",
|
||||
"@emotion/react": "^11.8.2",
|
||||
"@emotion/css": "^11.9.0",
|
||||
"@emotion/react": "^11.9.0",
|
||||
"@emotion/styled": "^11.8.1",
|
||||
"@hookform/resolvers": "2.8.8",
|
||||
"@monaco-editor/react": "^4.3.1",
|
||||
"@mui/icons-material": "^5.5.1",
|
||||
"@mui/lab": "^5.0.0-alpha.74",
|
||||
"@mui/material": "^5.5.2",
|
||||
"@reduxjs/toolkit": "^1.8.0",
|
||||
"@monaco-editor/react": "^4.4.1",
|
||||
"@mui/icons-material": "^5.6.0",
|
||||
"@mui/lab": "^5.0.0-alpha.76",
|
||||
"@mui/material": "^5.6.0",
|
||||
"@reduxjs/toolkit": "^1.8.1",
|
||||
"axios": "^0.26.1",
|
||||
"clsx": "^1.1.1",
|
||||
"dayjs": "^1.11.0",
|
||||
@ -26,23 +26,23 @@
|
||||
"lodash": "^4.17.21",
|
||||
"md5-hex": "^4.0.0",
|
||||
"monaco-editor": "^0.33.0",
|
||||
"nanoid": "^3.3.1",
|
||||
"next": "12.1.0",
|
||||
"next-i18next": "^10.5.0",
|
||||
"react": ">=17",
|
||||
"nanoid": "^3.3.2",
|
||||
"next": "12.1.4",
|
||||
"next-i18next": "^11.0.0",
|
||||
"react": "^17.0.0",
|
||||
"react-beautiful-dnd": "^13.1.0",
|
||||
"react-colorful": "^5.5.1",
|
||||
"react-dnd": "^15.1.1",
|
||||
"react-dnd": "^15.1.2",
|
||||
"react-dnd-html5-backend": "^15.1.2",
|
||||
"react-dom": ">=17",
|
||||
"react-dom": "^17.0.0",
|
||||
"react-google-login": "^5.2.2",
|
||||
"react-hook-form": "^7.28.1",
|
||||
"react-hook-form": "^7.29.0",
|
||||
"react-hot-toast": "2.2.0",
|
||||
"react-hotkeys-hook": "^3.4.4",
|
||||
"react-icons": "^4.3.1",
|
||||
"react-markdown": "^8.0.1",
|
||||
"react-query": "^3.34.16",
|
||||
"react-redux": "^7.2.6",
|
||||
"react-markdown": "^8.0.2",
|
||||
"react-query": "^3.34.19",
|
||||
"react-redux": "^7.2.8",
|
||||
"react-zoom-pan-pinch": "^2.1.3",
|
||||
"redux": "^4.1.2",
|
||||
"redux-persist": "^6.0.0",
|
||||
@ -53,25 +53,26 @@
|
||||
"webfontloader": "^1.6.28"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.17.8",
|
||||
"@babel/core": "^7.17.9",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@types/downloadjs": "^1.4.3",
|
||||
"@types/lodash": "^4.14.180",
|
||||
"@types/lodash": "^4.14.181",
|
||||
"@types/node": "17.0.23",
|
||||
"@types/react": "17.0.42",
|
||||
"@types/react": "18.0.0",
|
||||
"@types/react-beautiful-dnd": "^13.1.2",
|
||||
"@types/react-redux": "^7.1.23",
|
||||
"@types/tailwindcss": "^3.0.9",
|
||||
"@types/tailwindcss": "^3.0.10",
|
||||
"@types/uuid": "^8.3.4",
|
||||
"@types/webfontloader": "^1.6.34",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-config-next": "12.1.0",
|
||||
"next-sitemap": "^2.5.13",
|
||||
"csstype": "^3.0.11",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-config-next": "12.1.4",
|
||||
"next-sitemap": "^2.5.19",
|
||||
"postcss": "^8.4.12",
|
||||
"prettier": "^2.6.0",
|
||||
"sass": "^1.49.9",
|
||||
"prettier": "^2.6.2",
|
||||
"sass": "^1.50.0",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"typescript": "<4.6.0"
|
||||
}
|
||||
|
||||
BIN
client/public/images/templates/leafish.jpg
Normal file
BIN
client/public/images/templates/leafish.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 187 KiB |
@ -10,10 +10,10 @@
|
||||
"license": "Pela comunidade, para a comunidade."
|
||||
},
|
||||
"markdown": {
|
||||
"help-text": "Esta secção suporta formatação <1>markdown</1>."
|
||||
"help-text": "Esta seção suporta formatação <1>markdown</1>."
|
||||
},
|
||||
"date": {
|
||||
"present": "Presente"
|
||||
"present": "presente"
|
||||
},
|
||||
"subtitle": "Gerador de currículos gratuito e de código aberto.",
|
||||
"title": "Reactive Resume",
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
{
|
||||
"actions": {
|
||||
"app": "Ir para o App",
|
||||
"app": "Rodar aplicativo",
|
||||
"login": "Entrar",
|
||||
"logout": "Sair",
|
||||
"register": "Registrar-se"
|
||||
"logout": "Encerrar",
|
||||
"register": "Inscrição"
|
||||
},
|
||||
"features": {
|
||||
"heading": "Características",
|
||||
@ -12,30 +12,30 @@
|
||||
"export": "Exporte seu currículo para o formato JSON ou PDF",
|
||||
"free": "Gratuito, para sempre",
|
||||
"import": "Importe dados do LinkedIn, ou de um currículo em JSON",
|
||||
"languages": "Acessível em vários idiomas",
|
||||
"more": "E muito mais recursos interessantes, <1>leia tudo sobre isso aqui</1>",
|
||||
"languages": "Disponível em vários idiomas",
|
||||
"more": "E outros recursos interessantes, <1>veja todos aqui</1>",
|
||||
"tracking": "Sem rastreamento de usuários"
|
||||
}
|
||||
},
|
||||
"links": {
|
||||
"heading": "Links",
|
||||
"links": {
|
||||
"donate": "Doar",
|
||||
"donate": "Fazer doação",
|
||||
"github": "Código Fonte",
|
||||
"privacy": "Política de privacidade",
|
||||
"service": "Termos de serviço"
|
||||
}
|
||||
},
|
||||
"screenshots": {
|
||||
"heading": "Capturas de tela"
|
||||
"heading": "Imagens"
|
||||
},
|
||||
"testimonials": {
|
||||
"heading": "Depoimentos",
|
||||
"body": "Boa ou ruim, eu adoraria saber sua opinião sobre o Reactive Resume e como tem sido a experiência para você.<br/>Aqui estão algumas das mensagens enviadas por usuários em todo o mundo.",
|
||||
"contact": "Você pode entrar em contato comigo pelo <1>meu e-mail</1> ou por meio do formulário de contato no <3>meu site</3>."
|
||||
"body": "Considero importante a sua opinião, positiva ou negativa, a respeito do Reactive Resume, bem como a sua experiência ao usá-lo.<br/>Confira algumas das mensagens enviadas por pessoas de todo o mundo.",
|
||||
"contact": "Envie a sua mensagem por <1>e-mail</1> ou pelo formulário disponível <3>aqui</3>."
|
||||
},
|
||||
"summary": {
|
||||
"body": "O Reactive Resume é um construtor de currículos gratuito e de código aberto criado para tornar as tarefas mundanas de criar, atualizar e compartilhar seu currículo tão fáceis quanto 1, 2, 3. Com este aplicativo, você pode criar vários currículos, compartilhá-los com recrutadores ou amigos através de um link exclusivo e imprimi-los como PDF, tudo de graça, sem anúncios, sem rastreamento, sem perder a integridade e privacidade dos seus dados.",
|
||||
"body": "O Reactive Resume é um gerador de currículos, gratuito e de código aberto, desenvolvido para facilitar as tarefas tediosas de criação, atualização e divulgação de seu currículo. Este aplicativo possibilita a criação de múltiplos currículos, que podem ser compartilhados com recrutadores ou amigos com um link exclusivo ou impressos como PDF. Tudo isso de graça, sem anúncios, sem rastreamento, mantendo a integridade e privacidade dos seus dados.",
|
||||
"heading": "Resumo"
|
||||
}
|
||||
}
|
||||
|
||||
9
client/templates/Leafish/Leafish.module.scss
Normal file
9
client/templates/Leafish/Leafish.module.scss
Normal file
@ -0,0 +1,9 @@
|
||||
.page {}
|
||||
|
||||
.container {
|
||||
@apply grid grid-cols-2 gap-8 px-6 py-4;
|
||||
|
||||
.column {
|
||||
@apply col-span-1 flex flex-col;
|
||||
}
|
||||
}
|
||||
28
client/templates/Leafish/Leafish.tsx
Normal file
28
client/templates/Leafish/Leafish.tsx
Normal file
@ -0,0 +1,28 @@
|
||||
import { useMemo } from 'react';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import { PageProps } from '@/utils/template';
|
||||
|
||||
import { getSectionById } from '../sectionMap';
|
||||
import styles from './Leafish.module.scss';
|
||||
import Masthead from './widgets/Masthead';
|
||||
import Section from './widgets/Section';
|
||||
|
||||
const Leafish: React.FC<PageProps> = ({ page }) => {
|
||||
const isFirstPage = useMemo(() => page === 0, [page]);
|
||||
|
||||
const layout: string[][] = useAppSelector((state) => state.resume.metadata.layout[page]);
|
||||
|
||||
return (
|
||||
<div className={styles.page}>
|
||||
{isFirstPage && <Masthead />}
|
||||
|
||||
<div className={styles.container}>
|
||||
<div className={styles.column}>{layout[0].map((key) => getSectionById(key, Section))}</div>
|
||||
<div className={styles.column}>{layout[1].map((key) => getSectionById(key, Section))}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Leafish;
|
||||
19
client/templates/Leafish/widgets/Heading.tsx
Normal file
19
client/templates/Leafish/widgets/Heading.tsx
Normal file
@ -0,0 +1,19 @@
|
||||
import { Theme } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
|
||||
const Heading: React.FC = ({ children }) => {
|
||||
const theme: Theme = useAppSelector((state) => get(state.resume, 'metadata.theme', {}));
|
||||
|
||||
return (
|
||||
<h2
|
||||
className="pb-1 mb-2 font-bold uppercase opacity-75"
|
||||
style={{ borderBottomWidth: '3px', borderColor: theme.primary, color: theme.primary, display: 'inline-block' }}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
};
|
||||
|
||||
export default Heading;
|
||||
75
client/templates/Leafish/widgets/Masthead.tsx
Normal file
75
client/templates/Leafish/widgets/Masthead.tsx
Normal file
@ -0,0 +1,75 @@
|
||||
import { Email, Phone, Public, Room } from '@mui/icons-material';
|
||||
import { alpha } from '@mui/material';
|
||||
import { Theme } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import DataDisplay from '@/templates/shared/DataDisplay';
|
||||
import getProfileIcon from '@/utils/getProfileIcon';
|
||||
import { addHttp, formatLocation, getPhotoClassNames } from '@/utils/template';
|
||||
|
||||
const Masthead: React.FC = () => {
|
||||
const { name, photo, headline, summary, email, phone, website, location, profiles } = useAppSelector(
|
||||
(state) => state.resume.basics
|
||||
);
|
||||
const theme: Theme = useAppSelector((state) => get(state.resume, 'metadata.theme', {}));
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
className="flex items-center gap-4 p-6"
|
||||
id="Masterhead_main"
|
||||
style={{ backgroundColor: alpha(theme.primary, 0.2) }}
|
||||
>
|
||||
<div className="grid flex-1 gap-1">
|
||||
<h1 id="Masterhead_name">{name}</h1>
|
||||
<p style={{ color: theme.primary }} id="Masterhead_headline">
|
||||
{headline}
|
||||
</p>
|
||||
<p className="opacity-75" id="Masterhead_summary">
|
||||
{summary}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{photo.visible && !isEmpty(photo.url) && (
|
||||
<img
|
||||
alt={name}
|
||||
src={photo.url}
|
||||
width={photo.filters.size}
|
||||
height={photo.filters.size}
|
||||
className={getPhotoClassNames(photo.filters)}
|
||||
id="Masterhead_photo"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div
|
||||
className="grid gap-y-2 px-8 py-4"
|
||||
id="Masterhead_data"
|
||||
style={{ backgroundColor: alpha(theme.primary, 0.4), gridTemplateColumns: `repeat(2, minmax(0, 1fr))` }}
|
||||
>
|
||||
<DataDisplay icon={<Email />} link={`mailto:${email}`}>
|
||||
{email}
|
||||
</DataDisplay>
|
||||
|
||||
<DataDisplay icon={<Phone />} link={`tel:${phone}`}>
|
||||
{phone}
|
||||
</DataDisplay>
|
||||
|
||||
<DataDisplay icon={<Public />} link={addHttp(website)}>
|
||||
{website}
|
||||
</DataDisplay>
|
||||
|
||||
<DataDisplay icon={<Room />}>{formatLocation(location)}</DataDisplay>
|
||||
|
||||
{profiles.map(({ id, username, network, url }) => (
|
||||
<DataDisplay key={id} icon={getProfileIcon(network)} link={url && addHttp(url)}>
|
||||
{username}
|
||||
</DataDisplay>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Masthead;
|
||||
127
client/templates/Leafish/widgets/Section.tsx
Normal file
127
client/templates/Leafish/widgets/Section.tsx
Normal file
@ -0,0 +1,127 @@
|
||||
import { Email, Link, Phone } from '@mui/icons-material';
|
||||
import { ListItem, Section as SectionType } from '@reactive-resume/schema';
|
||||
import get from 'lodash/get';
|
||||
import isArray from 'lodash/isArray';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
import Markdown from '@/components/shared/Markdown';
|
||||
import { useAppSelector } from '@/store/hooks';
|
||||
import { SectionProps } from '@/templates/sectionMap';
|
||||
import DataDisplay from '@/templates/shared/DataDisplay';
|
||||
import { formatDateString } from '@/utils/date';
|
||||
import { parseListItemPath } from '@/utils/template';
|
||||
|
||||
import Heading from './Heading';
|
||||
|
||||
const Section: React.FC<SectionProps> = ({
|
||||
path,
|
||||
titlePath = 'title',
|
||||
subtitlePath = 'subtitle',
|
||||
headlinePath = 'headline',
|
||||
keywordsPath = 'keywords',
|
||||
}) => {
|
||||
const section: SectionType = useAppSelector((state) => get(state.resume, path, {}));
|
||||
const dateFormat: string = useAppSelector((state) => get(state.resume, 'metadata.date.format'));
|
||||
const primaryColor: string = useAppSelector((state) => get(state.resume, 'metadata.theme.primary'));
|
||||
|
||||
if (!section.visible) return null;
|
||||
|
||||
if (isArray(section.items) && isEmpty(section.items)) return null;
|
||||
|
||||
return (
|
||||
<section className="mb-4">
|
||||
<Heading>{section.name}</Heading>
|
||||
|
||||
<div
|
||||
className="grid items-start gap-4"
|
||||
style={{ gridTemplateColumns: `repeat(${section.columns}, minmax(0, 1fr))` }}
|
||||
id={`Section_${section.id}`}
|
||||
>
|
||||
{section.items.map((item: ListItem) => {
|
||||
const id = item.id,
|
||||
title = parseListItemPath(item, titlePath),
|
||||
subtitle = parseListItemPath(item, subtitlePath),
|
||||
headline = parseListItemPath(item, headlinePath),
|
||||
keywords: string[] = get(item, keywordsPath),
|
||||
url: string = get(item, 'url'),
|
||||
summary: string = get(item, 'summary'),
|
||||
level: string = get(item, 'level'),
|
||||
levelNum: number = get(item, 'levelNum'),
|
||||
phone: string = get(item, 'phone'),
|
||||
email: string = get(item, 'email'),
|
||||
date = formatDateString(get(item, 'date'), dateFormat);
|
||||
|
||||
return (
|
||||
<div key={id} id={id} className={`grid gap-1 mb-2 Section_${section.id}_inner`}>
|
||||
<div>
|
||||
{title && <div className="font-bold Section_title">{title}</div>}
|
||||
{subtitle && <div className="Section_subtitle">{subtitle}</div>}
|
||||
{date && (
|
||||
<div className="italic text-xs Section_date" style={{ color: primaryColor }}>
|
||||
({date})
|
||||
</div>
|
||||
)}
|
||||
{headline && <div className="opacity-50 Section_headline">{headline}</div>}
|
||||
</div>
|
||||
|
||||
{(level || levelNum > 0) && (
|
||||
<div className="grid gap-1">
|
||||
{level && <span className="opacity-75">{level}</span>}
|
||||
{levelNum > 0 && (
|
||||
<div className="flex">
|
||||
{Array.from(Array(5).keys()).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className="mr-1 h-3 w-3 rounded-full border-2"
|
||||
style={{
|
||||
borderColor: primaryColor,
|
||||
backgroundColor: levelNum / (10 / 5) > index ? primaryColor : '',
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{summary && (
|
||||
<div>
|
||||
<div className="italic text-xs" style={{ color: primaryColor }}>
|
||||
Overview
|
||||
</div>
|
||||
<Markdown className={`marker:text-[${primaryColor}]`}>{summary}</Markdown>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{url && (
|
||||
<DataDisplay icon={<Link />} link={url} className="text-xs">
|
||||
{url}
|
||||
</DataDisplay>
|
||||
)}
|
||||
|
||||
{keywords && <div>{keywords.join(', ')}</div>}
|
||||
|
||||
{(phone || email) && (
|
||||
<div className="grid gap-1">
|
||||
{phone && (
|
||||
<DataDisplay icon={<Phone />} link={`tel:${phone}`}>
|
||||
{phone}
|
||||
</DataDisplay>
|
||||
)}
|
||||
|
||||
{email && (
|
||||
<DataDisplay icon={<Email />} link={`mailto:${email}`}>
|
||||
{email}
|
||||
</DataDisplay>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Section;
|
||||
@ -4,6 +4,7 @@ import Castform from './Castform/Castform';
|
||||
import Gengar from './Gengar/Gengar';
|
||||
import Glalie from './Glalie/Glalie';
|
||||
import Kakuna from './Kakuna/Kakuna';
|
||||
import Leafish from './Leafish/Leafish';
|
||||
import Onyx from './Onyx/Onyx';
|
||||
import Pikachu from './Pikachu/Pikachu';
|
||||
|
||||
@ -51,6 +52,12 @@ const templateMap: Record<string, TemplateMeta> = {
|
||||
preview: '/images/templates/glalie.jpg',
|
||||
component: Glalie,
|
||||
},
|
||||
leafish: {
|
||||
id: 'leafish',
|
||||
name: 'Leafish',
|
||||
preview: '/images/templates/leafish.jpg',
|
||||
component: Leafish,
|
||||
},
|
||||
};
|
||||
|
||||
export default templateMap;
|
||||
|
||||
@ -7,14 +7,17 @@ x-env-shared: &env-shared
|
||||
- PUBLIC_SERVER_URL=http://localhost/api
|
||||
- PUBLIC_GOOGLE_CLIENT_ID=
|
||||
|
||||
x-env-database: &env-database
|
||||
environment:
|
||||
- POSTGRES_DB=postgres
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
|
||||
x-env-server: &env-server
|
||||
environment:
|
||||
- SECRET_KEY=
|
||||
- POSTGRES_HOST=postgres
|
||||
- POSTGRES_PORT=5432
|
||||
- POSTGRES_USER=postgres
|
||||
- POSTGRES_PASSWORD=postgres
|
||||
- POSTGRES_DATABASE=postgres
|
||||
- POSTGRES_SSL_CERT=
|
||||
- JWT_SECRET=
|
||||
- JWT_EXPIRY_TIME=604800
|
||||
@ -34,6 +37,9 @@ services:
|
||||
postgres:
|
||||
image: postgres:14.2-alpine
|
||||
container_name: postgres
|
||||
<<: *env-database
|
||||
ports:
|
||||
- 5432:5432
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
healthcheck:
|
||||
@ -61,6 +67,7 @@ services:
|
||||
container_name: server
|
||||
<<: *env-shared
|
||||
<<: *env-server
|
||||
<<: *env-database
|
||||
depends_on:
|
||||
- traefik
|
||||
- postgres
|
||||
|
||||
@ -65,6 +65,12 @@ This URL is used when export PDF functionality is used within the app and has to
|
||||
**Default Value:** `5432`
|
||||
**Description:** Port of the PostgreSQL Server
|
||||
|
||||
### `POSTGRES_DB`
|
||||
|
||||
**Required**: `yes`
|
||||
**Default Value:** `postgres`
|
||||
**Description:** Name of the Database in PostgreSQL Server
|
||||
|
||||
### `POSTGRES_USER`
|
||||
|
||||
**Required**: `yes`
|
||||
@ -77,12 +83,6 @@ This URL is used when export PDF functionality is used within the app and has to
|
||||
**Default Value:** `postgres`
|
||||
**Description:** Password of the PostgreSQL Server
|
||||
|
||||
### `POSTGRES_DATABASE`
|
||||
|
||||
**Required**: `yes`
|
||||
**Default Value:** `reactive_resume`
|
||||
**Description:** Name of the Database in PostgreSQL Server
|
||||
|
||||
### `POSTGRES_SSL_CERT`
|
||||
|
||||
**Required**: `no`
|
||||
|
||||
@ -15,13 +15,13 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@algolia/client-search": "^4.13.0",
|
||||
"@docusaurus/core": "2.0.0-beta.17",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.17",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"@docusaurus/core": "2.0.0-beta.18",
|
||||
"@docusaurus/preset-classic": "2.0.0-beta.18",
|
||||
"@mdx-js/react": "^2.1.1",
|
||||
"clsx": "^1.1.1",
|
||||
"prism-react-renderer": "^1.3.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
"react": "^17.0.0",
|
||||
"react-dom": "^17.0.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
@ -36,6 +36,6 @@
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react": "17.0.42"
|
||||
"@types/react": "^17.0.0"
|
||||
}
|
||||
}
|
||||
|
||||
16
package.json
16
package.json
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "reactive-resume",
|
||||
"version": "3.2.11",
|
||||
"version": "3.3.0",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"schema",
|
||||
@ -34,22 +34,22 @@
|
||||
"start": "env-cmd --silent concurrently --kill-others \"pnpm run start:*\""
|
||||
},
|
||||
"dependencies": {
|
||||
"concurrently": "^7.0.0",
|
||||
"concurrently": "^7.1.0",
|
||||
"env-cmd": "^10.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.16.0",
|
||||
"@typescript-eslint/parser": "^5.16.0",
|
||||
"@typescript-eslint/eslint-plugin": "^5.18.0",
|
||||
"@typescript-eslint/parser": "^5.18.0",
|
||||
"cz-conventional-changelog": "^3.3.0",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint": "^8.12.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-import": "^2.25.4",
|
||||
"eslint-plugin-import": "^2.26.0",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-simple-import-sort": "^7.0.0",
|
||||
"eslint-plugin-unused-imports": "^2.0.0",
|
||||
"husky": "^7.0.4",
|
||||
"prettier": "^2.6.0",
|
||||
"prettier": "^2.6.2",
|
||||
"standard-version": "^9.3.2",
|
||||
"typescript": "^4.5.5"
|
||||
"typescript": "<4.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
4310
pnpm-lock.yaml
generated
4310
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,7 @@
|
||||
"lint": "eslint --fix --ext .ts ./src"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.11.0",
|
||||
"eslint": "^8.12.0",
|
||||
"typescript": "<4.6.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,2 +0,0 @@
|
||||
create database reactive_resume;
|
||||
grant all privileges on database reactive_resume to postgres;
|
||||
@ -11,60 +11,60 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@nestjs/axios": "^0.0.7",
|
||||
"@nestjs/common": "^8.4.2",
|
||||
"@nestjs/common": "^8.4.4",
|
||||
"@nestjs/config": "^2.0.0",
|
||||
"@nestjs/core": "^8.4.2",
|
||||
"@nestjs/core": "^8.4.4",
|
||||
"@nestjs/jwt": "^8.0.0",
|
||||
"@nestjs/mapped-types": "^1.0.1",
|
||||
"@nestjs/passport": "^8.2.1",
|
||||
"@nestjs/platform-express": "^8.4.2",
|
||||
"@nestjs/schedule": "^1.0.2",
|
||||
"@nestjs/platform-express": "^8.4.4",
|
||||
"@nestjs/schedule": "^1.1.0",
|
||||
"@nestjs/serve-static": "^2.2.2",
|
||||
"@nestjs/terminus": "^8.0.6",
|
||||
"@nestjs/typeorm": "^8.0.3",
|
||||
"@sendgrid/mail": "^7.6.2",
|
||||
"@types/passport": "^1.0.7",
|
||||
"bcrypt": "^5.0.1",
|
||||
"cache-manager": "^3.6.0",
|
||||
"cache-manager": "^3.6.1",
|
||||
"class-transformer": "^0.5.1",
|
||||
"class-validator": "^0.13.2",
|
||||
"cookie-parser": "^1.4.6",
|
||||
"csvtojson": "^2.0.10",
|
||||
"dayjs": "^1.11.0",
|
||||
"googleapis": "^98.0.0",
|
||||
"googleapis": "^100.0.0",
|
||||
"joi": "^17.6.0",
|
||||
"lodash": "^4.17.21",
|
||||
"multer": "^1.4.4",
|
||||
"nanoid": "^3.3.1",
|
||||
"nanoid": "^3.3.2",
|
||||
"node-stream-zip": "^1.15.0",
|
||||
"passport": "^0.5.2",
|
||||
"passport-jwt": "^4.0.0",
|
||||
"passport-local": "^1.0.0",
|
||||
"pdf-lib": "^1.17.1",
|
||||
"pg": "^8.7.3",
|
||||
"playwright-chromium": "^1.20.1",
|
||||
"playwright-chromium": "^1.20.2",
|
||||
"reflect-metadata": "^0.1.13",
|
||||
"rimraf": "^3.0.2",
|
||||
"rxjs": "^7.5.5",
|
||||
"typeorm": "^0.2.45",
|
||||
"typeorm": "^0.2.34",
|
||||
"uuid": "^8.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nestjs/cli": "^8.2.4",
|
||||
"@nestjs/schematics": "^8.0.8",
|
||||
"@nestjs/cli": "^8.2.5",
|
||||
"@nestjs/schematics": "^8.0.10",
|
||||
"@reactive-resume/schema": "workspace:*",
|
||||
"@types/bcrypt": "^5.0.0",
|
||||
"@types/cookie-parser": "^1.4.2",
|
||||
"@types/express": "^4.17.13",
|
||||
"@types/multer": "^1.4.7",
|
||||
"@types/node": "^17.0.23",
|
||||
"eslint": "^8.11.0",
|
||||
"prettier": "^2.6.0",
|
||||
"eslint": "^8.12.0",
|
||||
"prettier": "^2.6.2",
|
||||
"source-map-support": "^0.5.21",
|
||||
"ts-loader": "^9.2.8",
|
||||
"ts-node": "^10.7.0",
|
||||
"tsconfig-paths": "^3.14.1",
|
||||
"typescript": "<4.6.0",
|
||||
"webpack": "^5.70.0"
|
||||
"webpack": "^5.72.0"
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,9 +21,9 @@ const validationSchema = Joi.object({
|
||||
// Database
|
||||
POSTGRES_HOST: Joi.string().required(),
|
||||
POSTGRES_PORT: Joi.number().default(5432),
|
||||
POSTGRES_DB: Joi.string().required(),
|
||||
POSTGRES_USER: Joi.string().required(),
|
||||
POSTGRES_PASSWORD: Joi.string().required(),
|
||||
POSTGRES_DATABASE: Joi.string().required(),
|
||||
POSTGRES_SSL_CERT: Joi.string().allow(''),
|
||||
|
||||
// Auth
|
||||
|
||||
@ -3,8 +3,8 @@ import { registerAs } from '@nestjs/config';
|
||||
export default registerAs('postgres', () => ({
|
||||
host: process.env.POSTGRES_HOST,
|
||||
port: parseInt(process.env.POSTGRES_PORT, 10) || 5432,
|
||||
database: process.env.POSTGRES_DB,
|
||||
username: process.env.POSTGRES_USER,
|
||||
password: process.env.POSTGRES_PASSWORD,
|
||||
database: process.env.POSTGRES_DATABASE,
|
||||
certificate: process.env.POSTGRES_SSL_CERT,
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user