Compare commits
No commits in common. "main" and "0.0.2" have entirely different histories.
19
.github/scripts/update-changelog.js
vendored
|
|
@ -1,19 +0,0 @@
|
||||||
const fs = require('fs');
|
|
||||||
|
|
||||||
module.exports = (version, prNumber) => {
|
|
||||||
const changelog = fs.readFileSync('CHANGELOG.md', 'utf8');
|
|
||||||
const changelogLines = changelog.split('\n');
|
|
||||||
const lastChangeIndex = changelogLines.findIndex((line) => line.startsWith('## ['));
|
|
||||||
|
|
||||||
const textToAppend = `
|
|
||||||
## [${version}] - ${new Date().toISOString().split('T')[0]}
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/${prNumber}))
|
|
||||||
`.trim();
|
|
||||||
|
|
||||||
changelogLines.splice(lastChangeIndex, 0, textToAppend + '\n');
|
|
||||||
|
|
||||||
fs.writeFileSync('CHANGELOG.md', changelogLines.join('\n'));
|
|
||||||
};
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
name: Modify changelog for dependency updates
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [labeled]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
if: github.event.label.name == 'dependencies' && github.repository == 'KonradSzwarc/devscard'
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
|
|
||||||
- name: Get project information
|
|
||||||
id: projectinfo
|
|
||||||
uses: gregoranders/nodejs-project-info@v0.0.20
|
|
||||||
- name: Get next possible versions
|
|
||||||
id: semvers
|
|
||||||
uses: WyriHaximus/github-action-next-semvers@v1
|
|
||||||
with:
|
|
||||||
version: ${{ steps.projectinfo.outputs.version }}
|
|
||||||
- name: Update package.json version
|
|
||||||
uses: reedyuk/npm-version@1.2.1
|
|
||||||
with:
|
|
||||||
version: ${{ steps.semvers.outputs.patch }}
|
|
||||||
- name: Update CHANGELOG.md
|
|
||||||
uses: actions/github-script@v6
|
|
||||||
with:
|
|
||||||
script: |
|
|
||||||
const script = require('.github/scripts/update-changelog.js');
|
|
||||||
const version = '${{ steps.semvers.outputs.patch }}';
|
|
||||||
const prNumber = '${{ github.event.pull_request.number }}';
|
|
||||||
|
|
||||||
script(version, prNumber);
|
|
||||||
- name: Commit changes
|
|
||||||
uses: stefanzweifel/git-auto-commit-action@v4
|
|
||||||
12
.github/workflows/main-branch.yml
vendored
|
|
@ -12,7 +12,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -26,7 +26,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -40,7 +40,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -58,7 +58,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -85,7 +85,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -121,7 +121,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Get project information
|
- name: Get project information
|
||||||
id: projectinfo
|
id: projectinfo
|
||||||
uses: gregoranders/nodejs-project-info@v0.0.20
|
uses: gregoranders/nodejs-project-info@v0.0.19
|
||||||
- name: Get changelog entries
|
- name: Get changelog entries
|
||||||
id: changelog_reader
|
id: changelog_reader
|
||||||
uses: mindsers/changelog-reader-action@v2
|
uses: mindsers/changelog-reader-action@v2
|
||||||
|
|
|
||||||
16
.github/workflows/pull-request.yml
vendored
|
|
@ -28,14 +28,14 @@ jobs:
|
||||||
ref: ${{ github.event.pull_request.head.sha }}
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
- name: Get project information
|
- name: Get project information
|
||||||
id: projectinfo-current
|
id: projectinfo-current
|
||||||
uses: gregoranders/nodejs-project-info@v0.0.20
|
uses: gregoranders/nodejs-project-info@v0.0.19
|
||||||
- name: Checkout main branch
|
- name: Checkout main branch
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
ref: ${{ github.event.pull_request.base.sha }}
|
ref: ${{ github.event.pull_request.base.sha }}
|
||||||
- name: Get project information
|
- name: Get project information
|
||||||
id: projectinfo-main
|
id: projectinfo-main
|
||||||
uses: gregoranders/nodejs-project-info@v0.0.20
|
uses: gregoranders/nodejs-project-info@v0.0.19
|
||||||
- name: Get next possible versions
|
- name: Get next possible versions
|
||||||
id: semvers
|
id: semvers
|
||||||
uses: WyriHaximus/github-action-next-semvers@v1
|
uses: WyriHaximus/github-action-next-semvers@v1
|
||||||
|
|
@ -59,7 +59,7 @@ jobs:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- name: Get project information
|
- name: Get project information
|
||||||
id: projectinfo
|
id: projectinfo
|
||||||
uses: gregoranders/nodejs-project-info@v0.0.20
|
uses: gregoranders/nodejs-project-info@v0.0.19
|
||||||
- name: Enforce changelog update
|
- name: Enforce changelog update
|
||||||
uses: dangoslen/changelog-enforcer@v3
|
uses: dangoslen/changelog-enforcer@v3
|
||||||
with:
|
with:
|
||||||
|
|
@ -82,7 +82,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -96,7 +96,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -110,7 +110,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -126,7 +126,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
@ -150,7 +150,7 @@ jobs:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: actions/setup-node@v3
|
- uses: actions/setup-node@v3
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 16
|
||||||
cache: npm
|
cache: npm
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
run: npm ci
|
run: npm ci
|
||||||
|
|
|
||||||
90
CHANGELOG.md
|
|
@ -2,98 +2,8 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
## [0.3.0] - 2023-08-25
|
|
||||||
|
|
||||||
### Breaking
|
|
||||||
|
|
||||||
- Bump astro-compress version to prevent failing install
|
|
||||||
|
|
||||||
## [0.2.1] - 2023-07-10
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/226))
|
|
||||||
|
|
||||||
## [0.2.0] - 2023-07-02
|
|
||||||
|
|
||||||
### Breaking
|
|
||||||
|
|
||||||
- Require Node.js 18.
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/225))
|
|
||||||
|
|
||||||
## [0.1.6] - 2023-05-08
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/220))
|
|
||||||
|
|
||||||
## [0.1.5] - 2023-05-01
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/219))
|
|
||||||
|
|
||||||
## [0.1.4] - 2023-04-05
|
|
||||||
|
|
||||||
### Workflow
|
|
||||||
|
|
||||||
- ci: use pull request URL instead of its API endpoint when generating changelog for dependency updates.
|
|
||||||
|
|
||||||
## [0.1.3] - 2023-03-27
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/214))
|
|
||||||
|
|
||||||
## [0.1.2] - 2023-03-24
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/212))
|
|
||||||
|
|
||||||
## [0.1.1] - 2023-03-20
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/213))
|
|
||||||
|
|
||||||
## [0.1.0] - 2023-03-13
|
|
||||||
|
|
||||||
### Features
|
|
||||||
|
|
||||||
- feat: improved target attribute in labelled values ([details](https://github.com/KonradSzwarc/devscard/pull/210))
|
|
||||||
|
|
||||||
## [0.0.6] - 2023-03-06
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/209))
|
|
||||||
|
|
||||||
## [0.0.5] - 2023-02-27
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/207))
|
|
||||||
|
|
||||||
## [0.0.4] - 2023-02-22
|
|
||||||
|
|
||||||
### Workflow
|
|
||||||
|
|
||||||
- ci: automatically update project version and changelog for Renovate's PRs
|
|
||||||
|
|
||||||
## [0.0.3] - 2023-02-21
|
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/202))
|
|
||||||
|
|
||||||
## [0.0.2] - 2023-02-16
|
## [0.0.2] - 2023-02-16
|
||||||
|
|
||||||
### Dependencies
|
|
||||||
|
|
||||||
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/201))
|
- chore(deps): update dependencies ([details](https://github.com/KonradSzwarc/devscard/pull/201))
|
||||||
|
|
||||||
## [0.0.1] - 2023-02-08
|
## [0.0.1] - 2023-02-08
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,6 @@
|
||||||
|
|
||||||
A fully customizable template to create your online (and paper) resume without writing a single line of code.
|
A fully customizable template to create your online (and paper) resume without writing a single line of code.
|
||||||
|
|
||||||
> [!IMPORTANT]
|
|
||||||
> This project will remain available but <ins>**won't receive updates**</ins>.
|
|
||||||
>
|
|
||||||
> If you are searching for a great framework to build your resume, **[check out Zenith](https://github.com/KonradSzwarc/zenith)**. It's a new iteration of this project utilizing recent Astro version capabilities that will provide you with much more features and customizability.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- **✍️ Intellisense** — provide your data in TypeScript files, getting autocompletion and description of each property right in your IDE.
|
- **✍️ Intellisense** — provide your data in TypeScript files, getting autocompletion and description of each property right in your IDE.
|
||||||
|
|
|
||||||
5900
package-lock.json
generated
64
package.json
|
|
@ -1,20 +1,19 @@
|
||||||
{
|
{
|
||||||
"name": "devscard",
|
"name": "devscard",
|
||||||
"description": "Template for creating a comprehensive virtual CV for developers.",
|
"description": "Template for creating a comprehensive virtual CV for developers.",
|
||||||
"version": "0.3.0",
|
"version": "0.0.2",
|
||||||
"private": true,
|
"private": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18",
|
"node": ">=14",
|
||||||
"npm": ">=9",
|
"npm": ">=6",
|
||||||
"yarn": "please-use-npm",
|
"yarn": "please-use-npm",
|
||||||
"pnpm": "please-use-npm"
|
"pnpm": "please-use-npm"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"postinstall": "npm run generate-favicons",
|
"postinstall": "npm run generate-favicons",
|
||||||
"dev": "astro dev",
|
"dev": "astro dev",
|
||||||
"prebuild": "npm run generate-favicons",
|
"prebuild": "move-file ./src/pages/pdf.astro ./src/pages/_pdf.astro && npm run generate-favicons",
|
||||||
"__prebuild": "move-file ./src/pages/pdf.astro ./src/pages/_pdf.astro && npm run generate-favicons",
|
"build": "astro build",
|
||||||
"build": "npm run generate-favicons && astro build",
|
|
||||||
"postbuild": "move-file ./src/pages/_pdf.astro ./src/pages/pdf.astro",
|
"postbuild": "move-file ./src/pages/_pdf.astro ./src/pages/pdf.astro",
|
||||||
"preview": "astro preview",
|
"preview": "astro preview",
|
||||||
"generate-pdf": "ts-node scripts/generate-pdf.ts",
|
"generate-pdf": "ts-node scripts/generate-pdf.ts",
|
||||||
|
|
@ -26,38 +25,38 @@
|
||||||
"check": "concurrently npm:*:check"
|
"check": "concurrently npm:*:check"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@floating-ui/dom": "1.4.4",
|
"@floating-ui/dom": "1.2.1",
|
||||||
"iconify-icon": "1.0.8",
|
"iconify-icon": "1.0.5",
|
||||||
"nanoid": "4.0.2"
|
"nanoid": "4.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@astrojs/image": "0.17.2",
|
"@astrojs/image": "0.15.0",
|
||||||
"@astrojs/react": "2.2.1",
|
"@astrojs/react": "2.0.2",
|
||||||
"@astrojs/tailwind": "4.0.0",
|
"@astrojs/tailwind": "3.0.1",
|
||||||
"@percy/cli": "1.26.2",
|
"@percy/cli": "1.18.0",
|
||||||
"@types/marked": "5.0.0",
|
"@types/marked": "4.0.8",
|
||||||
"astro": "2.8.0",
|
"astro": "2.0.12",
|
||||||
"astro-compress": "2.0.14",
|
"astro-compress": "1.1.33",
|
||||||
"concurrently": "8.2.0",
|
"concurrently": "7.6.0",
|
||||||
"date-fns": "2.30.0",
|
"date-fns": "2.29.3",
|
||||||
"favicons": "7.1.3",
|
"favicons": "7.1.0",
|
||||||
"iconify-icon-names": "1.1.0",
|
"iconify-icon-names": "1.1.0",
|
||||||
"immer": "10.0.2",
|
"immer": "9.0.19",
|
||||||
"locales-ts": "1.0.0",
|
"locales-ts": "1.0.0",
|
||||||
"marked": "5.1.1",
|
"marked": "4.2.12",
|
||||||
"move-file-cli": "3.0.0",
|
"move-file-cli": "3.0.0",
|
||||||
"photoswipe": "5.3.8",
|
"photoswipe": "5.3.5",
|
||||||
"postcss": "8.4.25",
|
"postcss": "8.4.21",
|
||||||
"prettier": "2.8.8",
|
"prettier": "2.8.4",
|
||||||
"prettier-plugin-astro": "0.10.0",
|
"prettier-plugin-astro": "0.8.0",
|
||||||
"prettier-plugin-tailwindcss": "0.3.0",
|
"prettier-plugin-tailwindcss": "0.2.3",
|
||||||
"puppeteer": "20.8.0",
|
"puppeteer": "19.7.1",
|
||||||
"puppeteer-report": "3.1.0",
|
"puppeteer-report": "3.1.0",
|
||||||
"rollup-plugin-visualizer": "5.9.2",
|
"rollup-plugin-visualizer": "5.9.0",
|
||||||
"tailwindcss": "3.3.2",
|
"tailwindcss": "3.2.6",
|
||||||
"ts-node": "10.9.1",
|
"ts-node": "10.9.1",
|
||||||
"type-fest": "3.13.0",
|
"type-fest": "3.5.7",
|
||||||
"typescript": "5.1.6"
|
"typescript": "4.9.5"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|
@ -66,6 +65,5 @@
|
||||||
"bugs": {
|
"bugs": {
|
||||||
"url": "https://github.com/KonradSzwarc/devscard/issues"
|
"url": "https://github.com/KonradSzwarc/devscard/issues"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/KonradSzwarc/devscard#readme",
|
"homepage": "https://github.com/KonradSzwarc/devscard#readme"
|
||||||
"packageManager": "pnpm@9.7.0+sha512.dc09430156b427f5ecfc79888899e1c39d2d690f004be70e05230b72cb173d96839587545d09429b55ac3c429c801b4dc3c0e002f653830a420fa2dd4e3cf9cf"
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
public/cv.pdf
Normal file
|
|
@ -32,7 +32,7 @@ const retry = async ({ promise, retries, retryTime }: RetryOptions): GoToReturn
|
||||||
const main = async () => {
|
const main = async () => {
|
||||||
const child = exec('npm run dev');
|
const child = exec('npm run dev');
|
||||||
|
|
||||||
const browser = await puppeteer.launch({ headless: 'new' });
|
const browser = await puppeteer.launch({ headless: true });
|
||||||
|
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|
||||||
|
|
|
||||||
BIN
src/assets/favorites/books/book-1.jpeg
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
src/assets/favorites/books/book-2.jpg
Normal file
|
After Width: | Height: | Size: 70 KiB |
BIN
src/assets/favorites/books/book-3.jpeg
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
src/assets/favorites/books/book-4.jpeg
Normal file
|
After Width: | Height: | Size: 43 KiB |
BIN
src/assets/favorites/media/media-1.jpeg
Normal file
|
After Width: | Height: | Size: 7 KiB |
BIN
src/assets/favorites/media/media-2.jpeg
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
src/assets/favorites/media/media-3.png
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
src/assets/favorites/media/media-4.png
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
src/assets/favorites/media/media-5.jpeg
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
src/assets/favorites/media/media-6.webp
Normal file
|
After Width: | Height: | Size: 800 B |
BIN
src/assets/favorites/people/person-1.jpg
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
src/assets/favorites/people/person-2.jpeg
Normal file
|
After Width: | Height: | Size: 36 KiB |
BIN
src/assets/favorites/people/person-3.jpeg
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
src/assets/favorites/people/person-4.jpeg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/favorites/people/person-5.jpg
Normal file
|
After Width: | Height: | Size: 17 KiB |
BIN
src/assets/favorites/people/person-6.jpeg
Normal file
|
After Width: | Height: | Size: 5.4 KiB |
BIN
src/assets/favorites/videos/video-1.jpeg
Normal file
|
After Width: | Height: | Size: 134 KiB |
BIN
src/assets/favorites/videos/video-2.jpeg
Normal file
|
After Width: | Height: | Size: 73 KiB |
BIN
src/assets/favorites/videos/video-3.jpeg
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
src/assets/logos/facebook-logo.png
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/logos/gitlab-logo.png
Normal file
|
After Width: | Height: | Size: 3.2 KiB |
BIN
src/assets/logos/google-logo.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 6.4 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 11 KiB |
BIN
src/assets/logos/wroclaw-university-of-technology.jpg
Normal file
|
After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 4.6 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 9 KiB |
BIN
src/assets/portfolio/project-1-screenshot-1.jpg
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
src/assets/portfolio/project-1-screenshot-2.jpg
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/assets/portfolio/project-1-screenshot-3.jpg
Normal file
|
After Width: | Height: | Size: 183 KiB |
BIN
src/assets/portfolio/project-1.jpeg
Normal file
|
After Width: | Height: | Size: 18 KiB |
BIN
src/assets/portfolio/project-2.jpeg
Normal file
|
After Width: | Height: | Size: 13 KiB |
BIN
src/assets/portfolio/project-3.jpeg
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
src/assets/portfolio/project-4.jpeg
Normal file
|
After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 14 KiB |
BIN
src/assets/testimonials/testimonial-1.jpeg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/testimonials/testimonial-2.jpeg
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
src/assets/testimonials/testimonial-3.jpeg
Normal file
|
After Width: | Height: | Size: 112 KiB |
|
|
@ -24,17 +24,10 @@ const stripIndent = (str: string) => {
|
||||||
return str.replace(regex, '');
|
return str.replace(regex, '');
|
||||||
};
|
};
|
||||||
|
|
||||||
const parseMarkdown = (str: string) =>
|
|
||||||
marked.parse(stripIndent(str), {
|
|
||||||
breaks: true,
|
|
||||||
headerIds: false,
|
|
||||||
mangle: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const { content, classList } = Astro.props;
|
const { content, classList } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<div set:html={parseMarkdown(content)} class:list={['description', ...classList]} />
|
<div set:html={marked.parse(stripIndent(content), { breaks: true })} class:list={['description', ...classList]} />
|
||||||
|
|
||||||
<style is:global>
|
<style is:global>
|
||||||
.description ul {
|
.description ul {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import type { Data } from '@/types/data';
|
import type { Data } from '@/types/data';
|
||||||
import { produce } from 'immer';
|
import produce from 'immer';
|
||||||
import type { PreciseData } from './get-cv-data';
|
import type { PreciseData } from './get-cv-data';
|
||||||
import type { DataTransformer } from './transformers';
|
import type { DataTransformer } from './transformers';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,20 @@ import type { ReadonlyDeep } from 'type-fest';
|
||||||
const config = {
|
const config = {
|
||||||
i18n: {
|
i18n: {
|
||||||
locale: enUS,
|
locale: enUS,
|
||||||
dateFormat: 'MMM yyyy',
|
dateFormat: 'MMMM yyyy',
|
||||||
translations: {
|
translations: {
|
||||||
now: 'Present',
|
now: 'now',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
meta: {
|
meta: {
|
||||||
title: 'Juyoung Lee - Resume',
|
title: 'Mark Freeman - Senior React Developer',
|
||||||
description: 'Resume about Juyoung Lee',
|
description:
|
||||||
|
'Lorem ipsum dolor sit amet, consectetur adipiscing elit. In sodales ac dui at vestibulum. In condimentum metus id dui tincidunt, in blandit mi vehicula.',
|
||||||
faviconPath: '/src/assets/my-image.jpeg',
|
faviconPath: '/src/assets/my-image.jpeg',
|
||||||
},
|
},
|
||||||
pdf: {
|
pdf: {
|
||||||
footer:
|
footer:
|
||||||
//'I hereby give consent for my personal data included in my application to be processed for the purposes of the recruitment process.',
|
'I hereby give consent for my personal data included in my application to be processed for the purposes of the recruitment process.',
|
||||||
'',
|
|
||||||
},
|
},
|
||||||
} as const satisfies ReadonlyDeep<Config>;
|
} as const satisfies ReadonlyDeep<Config>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,6 @@ link({ name: '...', url: '...' }) — returns link object with a custom name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// GENERAL
|
// GENERAL
|
||||||
export const tiktok = createLinkFactory({
|
|
||||||
name: 'TikTok',
|
|
||||||
icon: 'fa6-brands:tiktok',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const facebook = createLinkFactory({
|
export const facebook = createLinkFactory({
|
||||||
name: 'Facebook',
|
name: 'Facebook',
|
||||||
|
|
|
||||||
|
|
@ -18,83 +18,6 @@ skill({ description: '...' }) — returns skill with a description displayed whe
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export const python = createSkillFactory({
|
|
||||||
name: 'Python',
|
|
||||||
icon: 'simple-icons:python',
|
|
||||||
iconColor: '#3776AB',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const mysql = createSkillFactory({
|
|
||||||
name: 'MySQL',
|
|
||||||
icon: 'simple-icons:mysql',
|
|
||||||
iconColor: '#4479A1',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const coldfusion = createSkillFactory({
|
|
||||||
name: 'ColdFusion',
|
|
||||||
icon: 'simple-icons:c',
|
|
||||||
iconColor: '#77a8f7',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const dreamweaver = createSkillFactory({
|
|
||||||
name: 'Dreamweaver',
|
|
||||||
icon: 'simple-icons:adobedreamweaver',
|
|
||||||
iconColor: '#FF61F6',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const jquery = createSkillFactory({
|
|
||||||
name: 'jQuery',
|
|
||||||
icon: 'simple-icons:jquery',
|
|
||||||
iconColor: '#0769AD',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const bootstrap = createSkillFactory({
|
|
||||||
name: 'Bootstrap',
|
|
||||||
icon: 'simple-icons:bootstrap',
|
|
||||||
iconColor: '#7952B3',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const html = createSkillFactory({
|
|
||||||
name: 'HTML',
|
|
||||||
icon: 'simple-icons:html5',
|
|
||||||
iconColor: '#E34F26',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const css = createSkillFactory({
|
|
||||||
name: 'CSS',
|
|
||||||
icon: 'simple-icons:css3',
|
|
||||||
iconColor: '#1572B6',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const javascript = createSkillFactory({
|
|
||||||
name: 'JavaScript',
|
|
||||||
icon: 'simple-icons:javascript',
|
|
||||||
iconColor: '#dec81b',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const java = createSkillFactory({
|
|
||||||
name: 'Java',
|
|
||||||
icon: 'simple-icons:coffeescript',
|
|
||||||
iconColor: '#2F2625',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const processing = createSkillFactory({
|
|
||||||
name: 'Processing',
|
|
||||||
icon: 'simple-icons:processingfoundation',
|
|
||||||
iconColor: '#006699',
|
|
||||||
url: '#',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const apolloGraphql = createSkillFactory({
|
export const apolloGraphql = createSkillFactory({
|
||||||
name: 'Apollo GraphQL',
|
name: 'Apollo GraphQL',
|
||||||
icon: 'simple-icons:apollographql',
|
icon: 'simple-icons:apollographql',
|
||||||
|
|
|
||||||
|
|
@ -11,22 +11,13 @@ const educationSectionData = {
|
||||||
},
|
},
|
||||||
diplomas: [
|
diplomas: [
|
||||||
{
|
{
|
||||||
title: 'Master of Science (M.S.) in Engineering, Concentration in Aerospace Engineering',
|
title: 'Information Technology',
|
||||||
institution: 'Virginia Commonwealth University',
|
institution: 'Wrocław University of Science and Technology',
|
||||||
image: import('@/assets/logos/vcu.png'),
|
image: import('@/assets/logos/wroclaw-university-of-technology.jpg'),
|
||||||
dates: [new Date('2024-02'), null],
|
dates: [new Date('2014.10'), new Date('2016.07')],
|
||||||
description: '2024-',
|
description: 'Master degree. Specialization in software development.',
|
||||||
links: [website({ url: 'https://egr.vcu.edu' })],
|
links: [website({ url: '#' })],
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: 'Bachelor of Science (B.S.) in Computer Science 🎓',
|
|
||||||
institution: 'San Francisco State University',
|
|
||||||
image: import('@/assets/logos/sfsu.png'),
|
|
||||||
dates: [new Date('2018-02'), new Date('2020-02')],
|
|
||||||
description: 'Graduated: 2020',
|
|
||||||
links: [website({ url: 'https://cs.sfsu.edu' })],
|
|
||||||
},
|
|
||||||
/*
|
|
||||||
{
|
{
|
||||||
title: 'Information Technology',
|
title: 'Information Technology',
|
||||||
institution: 'Wrocław University of Science and Technology',
|
institution: 'Wrocław University of Science and Technology',
|
||||||
|
|
@ -34,7 +25,7 @@ const educationSectionData = {
|
||||||
dates: [new Date('2011.10'), new Date('2014.07')],
|
dates: [new Date('2011.10'), new Date('2014.07')],
|
||||||
description: "Bachelor's degree. Specialization in application development.",
|
description: "Bachelor's degree. Specialization in application development.",
|
||||||
links: [website({ url: '#' })],
|
links: [website({ url: '#' })],
|
||||||
},*/
|
},
|
||||||
],
|
],
|
||||||
} as const satisfies ReadonlyDeep<EducationSection>;
|
} as const satisfies ReadonlyDeep<EducationSection>;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import type { ExperienceSection } from '@/types/sections/experience-section.types';
|
import type { ExperienceSection } from '@/types/sections/experience-section.types';
|
||||||
import type { ReadonlyDeep } from 'type-fest';
|
import type { ReadonlyDeep } from 'type-fest';
|
||||||
import { facebook, github, tiktok, instagram, linkedin, twitter, website, youtube } from '../helpers/links';
|
import { facebook, github, instagram, linkedin, twitter, website } from '../helpers/links';
|
||||||
import {
|
import {
|
||||||
chakraUi,
|
chakraUi,
|
||||||
eslint,
|
eslint,
|
||||||
|
|
@ -13,17 +13,6 @@ import {
|
||||||
tailwindCss,
|
tailwindCss,
|
||||||
typescript,
|
typescript,
|
||||||
vue,
|
vue,
|
||||||
mysql,
|
|
||||||
coldfusion,
|
|
||||||
html,
|
|
||||||
css,
|
|
||||||
javascript,
|
|
||||||
dreamweaver,
|
|
||||||
jquery,
|
|
||||||
bootstrap,
|
|
||||||
java,
|
|
||||||
processing,
|
|
||||||
python,
|
|
||||||
} from '../helpers/skills';
|
} from '../helpers/skills';
|
||||||
|
|
||||||
const experienceSectionData = {
|
const experienceSectionData = {
|
||||||
|
|
@ -34,74 +23,60 @@ const experienceSectionData = {
|
||||||
visible: true,
|
visible: true,
|
||||||
},
|
},
|
||||||
jobs: [
|
jobs: [
|
||||||
// {
|
|
||||||
// role: 'Founder',
|
|
||||||
// company: 'Mimory AI',
|
|
||||||
// image: import('@/assets/logos/mimory.jpg'),
|
|
||||||
// dates: [new Date('2025-05-02'), null], //null ], // Use null for 'Present'
|
|
||||||
// description: ``,
|
|
||||||
// tagsList: {
|
|
||||||
// title: '',
|
|
||||||
// tags: [],
|
|
||||||
// },
|
|
||||||
// links: [
|
|
||||||
// tiktok({ url: 'https://tiktok.com/@mimoryai' }),
|
|
||||||
// youtube({ url: 'https://youtube.com/@mimoryai' }),
|
|
||||||
// instagram({ url: 'https://instagram.com/mimoryai' }),
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
role: 'Web Programmer/Systems Analyst',
|
role: 'Senior front-end developer',
|
||||||
company: 'National Training and Data Center',
|
company: 'Google',
|
||||||
image: import('@/assets/logos/vcu.png'),
|
image: import('@/assets/logos/google-logo.jpg'),
|
||||||
dates: [new Date('2021-03-02'), null], //null ], // Use null for 'Present'
|
dates: [new Date('2020-02'), null],
|
||||||
description: `
|
description: `
|
||||||
- Developed and maintained server-side modules for high-volume data systems funded by the Social Security Administration (SSA), implementing reliable data processing logic and improving system scalability across large datasets
|
- In tristique vulputate augue vel egestas.
|
||||||
- Designed scalable backend systems aligned with evolving program requirements, improving long-term maintainability and supporting operational efficiency
|
- Quisque ac imperdiet tortor, at lacinia ex.
|
||||||
- Implemented backend security and privacy enhancements in alignment with federal security standards (FISMA), improving data protection and system resilience
|
- Duis vel ex hendrerit, commodo odio sed, aliquam enim.
|
||||||
- Monitored application performance, diagnosing and resolving issues to ensure high system availability and reliable backend operations
|
- Ut arcu nulla, tincidunt eget arcu eget, molestie vulputate nisi.
|
||||||
|
- Nunc malesuada leo et est iaculis facilisis.
|
||||||
|
- Fusce eu urna ut magna malesuada fringilla.
|
||||||
`,
|
`,
|
||||||
tagsList: {
|
tagsList: {
|
||||||
title: '',
|
title: 'Technologies',
|
||||||
tags: [mysql(), coldfusion()],
|
tags: [react(), nextJs(), typescript(), nx(), firebase()],
|
||||||
},
|
},
|
||||||
links: [], //[facebook({ url: '#' }), linkedin({ url: '#' })],
|
links: [facebook({ url: '#' }), linkedin({ url: '#' })],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'Web Accessibility Developer',
|
role: 'React.js developer',
|
||||||
company: 'San Francisco State University',
|
company: 'Facebook',
|
||||||
image: import('@/assets/logos/sfsu.png'),
|
image: import('@/assets/logos/facebook-logo.png'),
|
||||||
dates: [new Date('2018-08-02'), new Date('2020-05-02')],
|
dates: [new Date('2019-04'), new Date('2020-02')],
|
||||||
description: `
|
description: `
|
||||||
- Fixed HTML, CSS, JavaScript on campus and 3rd party websites and learning platform (iLearn), and maintained campus-wide best practices for meeting web accessibility requirements WCAG 2.0 (AA, AAA)
|
- Aenean eget ultricies felis. Pellentesque dictum massa ut tellus eleifend, sed posuere massa mattis.
|
||||||
- Converted documents accessible using PDF Accessibility Checker, CommonLook, MS Word, and corrected errors in headings, reading order, images, tables, etc.
|
- Ut posuere massa lacus, eleifend molestie tortor auctor vel.
|
||||||
- Created text and HTML-based content specific to the accessibility best practices
|
- Sed sed sollicitudin eros, id ultricies mi. Aliquam sodales elit vel ante tempor, non vehicula nibh facilisis.
|
||||||
- Provided expert technical assistance and group training for campus-wide IT personnel (webmasters, newsletter editors)
|
- Cras feugiat ultricies maximus. Aliquam tristique ex odio, ac semper urna accumsan a.
|
||||||
- Documented defects using manual and automated testing tools, and collaborated with development teams to establish technical specifications
|
|
||||||
- Managed accessible computer stations, and proctored exams for students who need accommodation
|
|
||||||
- Tools used: debugging tools in Firefox/Chrome, Drupal, WordPress, JAWS, WAVE, ARIA, Colour Contrast Analyzer, Link Klipper, Compliance Sheriff (automated testing tool), etc.
|
|
||||||
`,
|
`,
|
||||||
tagsList: {
|
tagsList: {
|
||||||
title: '',
|
title: 'Technologies',
|
||||||
tags: [html(), css(), javascript()],
|
tags: [react(), reactQuery(), chakraUi(), eslint()],
|
||||||
},
|
},
|
||||||
links: [], //[website({ url: '#' }), instagram({ url: '#' })],
|
links: [website({ url: '#' }), instagram({ url: '#' })],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
role: 'Java Teaching Assistant',
|
role: 'Junior front-end developer',
|
||||||
company: 'San Francisco Unified School District',
|
company: 'GitLab',
|
||||||
image: import('@/assets/logos/sfusd.png'),
|
image: import('@/assets/logos/gitlab-logo.png'),
|
||||||
dates: [new Date('2019-01-02'), new Date('2019-05-02')],
|
dates: [new Date('2016-09'), new Date('2019-04')],
|
||||||
description: `
|
description: `
|
||||||
- As part of the National Science Foundation-funded program (CS4SF), taught object-oriented Java programming in 9-12th grade classroom, leveraging knowledge acquired from university coursework
|
Nulla volutpat justo ante, rhoncus posuere massa egestas in:
|
||||||
- Assisted teacher to help 30-40 students debug in-class coding assignments, and engaged students in learning activities
|
|
||||||
- Maintained positive, calm attitude and soft voice, and worked under teacher's direction to establish clean and comfortable classroom 🤗
|
- Quisque pellentesque, dolor nec sollicitudin iaculis, sem velit consequat ligula, eget tempus ligula leo et est.
|
||||||
|
- Maecenas ut elit sit amet nibh maximus condimentum in nec lorem. Pellentesque tincidunt odio vel leo suscipit, in interdum mi gravida.
|
||||||
|
|
||||||
|
Donec non vulputate augue 🤓
|
||||||
`,
|
`,
|
||||||
tagsList: {
|
tagsList: {
|
||||||
title: '',
|
title: 'Technologies',
|
||||||
tags: [java(), processing()],
|
tags: [vue(), tailwindCss(), pnpm()],
|
||||||
},
|
},
|
||||||
links: [], //[twitter({ url: '#' }), github({ url: '#' })],
|
links: [twitter({ url: '#' }), github({ url: '#' })],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as const satisfies ReadonlyDeep<ExperienceSection>;
|
} as const satisfies ReadonlyDeep<ExperienceSection>;
|
||||||
|
|
|
||||||
|
|
@ -10,12 +10,12 @@ import testimonialsData from './testimonials-section.data';
|
||||||
|
|
||||||
export const sections = {
|
export const sections = {
|
||||||
main: mainData,
|
main: mainData,
|
||||||
//skills: skillsData,
|
skills: skillsData,
|
||||||
experience: experienceData,
|
experience: experienceData,
|
||||||
portfolio: portfolioData,
|
portfolio: portfolioData,
|
||||||
education: educationData,
|
education: educationData,
|
||||||
//testimonials: testimonialsData,
|
testimonials: testimonialsData,
|
||||||
//favorites: favoritesData,
|
favorites: favoritesData,
|
||||||
} as const satisfies ReadonlyDeep<Sections>;
|
} as const satisfies ReadonlyDeep<Sections>;
|
||||||
|
|
||||||
export default sections;
|
export default sections;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import type { MainSection } from '@/types/sections/main-section.types';
|
import type { MainSection } from '@/types/sections/main-section.types';
|
||||||
import type { ReadonlyDeep } from 'type-fest';
|
import type { ReadonlyDeep } from 'type-fest';
|
||||||
import { facebook, github, linkedin, twitter, website } from '../helpers/links';
|
import { facebook, github, linkedin, twitter } from '../helpers/links';
|
||||||
|
|
||||||
const mainSectionData = {
|
const mainSectionData = {
|
||||||
config: {
|
config: {
|
||||||
|
|
@ -10,35 +10,30 @@ const mainSectionData = {
|
||||||
visible: true,
|
visible: true,
|
||||||
},
|
},
|
||||||
image: import('@/assets/my-image.jpeg'),
|
image: import('@/assets/my-image.jpeg'),
|
||||||
fullName: 'Jay Lee',
|
fullName: 'Mark Freeman',
|
||||||
role: 'Software Engineer',
|
role: 'Senior React Developer',
|
||||||
details: [
|
details: [
|
||||||
// { label: 'Phone', value: '605 475 6961', url: 'tel:605 475 6961' },
|
{ label: 'Phone', value: '+48 604 343 212' },
|
||||||
{ label: 'Location', value: 'San Francisco, CA' },
|
{ label: 'Email', value: 'mark.freeman.dev@gmail.com' },
|
||||||
{ label: 'Email', value: '✉️', url: 'https://go.juyung.com/email' },
|
{ label: 'From', value: 'Warsaw, Poland' },
|
||||||
// { label: 'Salary range', value: '18 000 - 25 000 PLN' },
|
{ label: 'Salary range', value: '18 000 - 25 000 PLN' },
|
||||||
],
|
],
|
||||||
pdfDetails: [
|
pdfDetails: [
|
||||||
// { label: 'Phone', value: '605 475 6961' },
|
{ label: 'Phone', value: '+48 604 343 212' },
|
||||||
// { label: 'Email', value: 'mark.freeman.dev@gmail.com' },
|
{ label: 'Email', value: 'mark.freeman.dev@gmail.com' },
|
||||||
{ label: 'Website', value: 'juyung.com', url: 'https://juyung.com', fullRow: true },
|
{ label: 'LinkedIn', value: '/in/mark-freeman', url: 'https://linkedin.com' },
|
||||||
{ label: 'GitHub', value: 'git.juyung.com', url: 'https://git.juyung.com' },
|
{ label: 'GitHub', value: '/mark-freeman', url: 'https://github.com' },
|
||||||
{ label: 'LinkedIn', value: 'job.juyung.com', url: 'https://job.juyung.com' },
|
{ label: 'Website', value: 'mark-freeman-personal-website.com', url: '/', fullRow: true },
|
||||||
],
|
],
|
||||||
description: `I’m a software engineer. Previously, I worked as a web accessibility developer and taught Java programming. I have a Bachelor's in Computer Science and am currently pursuing a Master’s in Aerospace Engineering.`,
|
description:
|
||||||
// 'Lorem ipsum dolor sit amet, consectetur **adipiscing elit**. In sodales ac dui at *vestibulum*. In condimentum metus id dui tincidunt, in blandit mi [vehicula](/). Nulla lacinia, erat sit amet elementum vulputate, lectus mauris volutpat mi, vitae accumsan metus elit ut nunc. Vestibulum lacinia enim eget eros fermentum scelerisque. Proin augue leo, posuere ut imperdiet vitae, fermentum eu ipsum. Sed sed neque sagittis, posuere urna nec, commodo leo. Pellentesque posuere justo vitae massa volutpat maximus.',
|
'Lorem ipsum dolor sit amet, consectetur **adipiscing elit**. In sodales ac dui at *vestibulum*. In condimentum metus id dui tincidunt, in blandit mi [vehicula](/). Nulla lacinia, erat sit amet elementum vulputate, lectus mauris volutpat mi, vitae accumsan metus elit ut nunc. Vestibulum lacinia enim eget eros fermentum scelerisque. Proin augue leo, posuere ut imperdiet vitae, fermentum eu ipsum. Sed sed neque sagittis, posuere urna nec, commodo leo. Pellentesque posuere justo vitae massa volutpat maximus.',
|
||||||
tags: [], //[{ name: 'Open for freelance' }, { name: 'Available for mentoring' }, { name: 'Working on side project' }],
|
tags: [{ name: 'Open for freelance' }, { name: 'Available for mentoring' }, { name: 'Working on side project' }],
|
||||||
// action: {
|
action: {
|
||||||
// label: 'Download Resume',
|
label: 'Download CV',
|
||||||
// url: '/cv.pdf',
|
url: '/cv.pdf',
|
||||||
// downloadedFileName: 'Resume-Juyoung.pdf',
|
downloadedFileName: 'CV-Mark_Freeman.pdf',
|
||||||
// },
|
},
|
||||||
links: [
|
links: [facebook({ url: '#' }), github({ url: '#' }), linkedin({ url: '#' }), twitter({ url: '#' })],
|
||||||
/*facebook({ url: '#' }),*/
|
|
||||||
website({ url: 'https://juyung.com' }),
|
|
||||||
github({ url: 'https://git.juyung.com' }),
|
|
||||||
linkedin({ url: 'https://job.juyung.com' }),
|
|
||||||
], // twitter({ url: '#' })],
|
|
||||||
} as const satisfies ReadonlyDeep<MainSection>;
|
} as const satisfies ReadonlyDeep<MainSection>;
|
||||||
|
|
||||||
export default mainSectionData;
|
export default mainSectionData;
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ import {
|
||||||
|
|
||||||
const portfolioSectionData = {
|
const portfolioSectionData = {
|
||||||
config: {
|
config: {
|
||||||
title: 'Certifications',
|
title: 'Projects',
|
||||||
slug: 'certifications',
|
slug: 'projects',
|
||||||
icon: 'fa6-solid:rocket',
|
icon: 'fa6-solid:rocket',
|
||||||
visible: true,
|
visible: true,
|
||||||
screenshots: {
|
screenshots: {
|
||||||
|
|
@ -31,58 +31,97 @@ const portfolioSectionData = {
|
||||||
},
|
},
|
||||||
projects: [
|
projects: [
|
||||||
{
|
{
|
||||||
name: 'Trusted Tester',
|
name: 'Golden Bulls',
|
||||||
image: import('@/assets/portfolio/tt.png'),
|
image: import('@/assets/portfolio/project-1.jpeg'),
|
||||||
dates: [new Date('2022-08-02'), null],
|
dates: [new Date('2020-03'), null],
|
||||||
description: 'U.S. Department of Homeland Security',
|
|
||||||
details: [
|
details: [
|
||||||
{ label: 'Credential ID', value: 'TT-2208-03281' },
|
{ label: 'Team size', value: '1 person' },
|
||||||
// { label: 'Company', value: 'None' },
|
{ label: 'My role', value: ['Front-end Developer', 'Designer'] },
|
||||||
// { label: 'Category', value: ['Web app', 'Open source'] },
|
{ label: 'Company', value: 'None' },
|
||||||
|
{ label: 'Category', value: ['Web app', 'Open source'] },
|
||||||
],
|
],
|
||||||
pdfDetails: [
|
pdfDetails: [
|
||||||
// { label: 'Demo', value: 'https://golden-bulls-d73jd7.netlify.app', url: '#' },
|
{ label: 'Demo', value: 'https://golden-bulls-d73jd7.netlify.app', url: '#' },
|
||||||
// { label: 'Repository', value: 'https://github.com/mark-freeman/golden-bulls', url: '#' },
|
{ label: 'Repository', value: 'https://github.com/mark-freeman/golden-bulls', url: '#' },
|
||||||
],
|
],
|
||||||
screenshots: [
|
screenshots: [
|
||||||
{ src: import('@/assets/portfolio/tt-certificate.png'), alt: 'Trusted Tester Certification' },
|
{ src: import('@/assets/portfolio/project-1-screenshot-1.jpg'), alt: 'First screenshot' },
|
||||||
// { src: import('@/assets/portfolio/project-1-screenshot-2.jpg'), alt: 'Second screenshot' },
|
{ src: import('@/assets/portfolio/project-1-screenshot-2.jpg'), alt: 'Second screenshot' },
|
||||||
// { src: import('@/assets/portfolio/project-1-screenshot-3.jpg'), alt: 'Third screenshot' },
|
{ src: import('@/assets/portfolio/project-1-screenshot-3.jpg'), alt: 'Third screenshot' },
|
||||||
],
|
],
|
||||||
//description: '',
|
description:
|
||||||
// 'In tristique vulputate augue vel egestas. Quisque ac imperdiet tortor, at lacinia ex. Duis vel ex hendrerit, commodo odio sed, aliquam enim. Ut arcu nulla, tincidunt eget arcu eget, molestie vulputate nisi. Nunc malesuada leo et est iaculis facilisis.',
|
'In tristique vulputate augue vel egestas. Quisque ac imperdiet tortor, at lacinia ex. Duis vel ex hendrerit, commodo odio sed, aliquam enim. Ut arcu nulla, tincidunt eget arcu eget, molestie vulputate nisi. Nunc malesuada leo et est iaculis facilisis.',
|
||||||
tagsList: {
|
tagsList: {
|
||||||
title: '', //'Technologies',
|
title: 'Technologies',
|
||||||
tags: [], //[nextJs(), sass(), pnpm(), eslint(), prettier()],
|
tags: [nextJs(), sass(), pnpm(), eslint(), prettier()],
|
||||||
},
|
},
|
||||||
links: [], //[mockups({ url: '#' }), demo({ url: '#' })],
|
links: [mockups({ url: '#' }), demo({ url: '#' })],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'JAWS Certified',
|
name: 'TruQuest',
|
||||||
image: import('@/assets/portfolio/jaws.png'),
|
image: import('@/assets/portfolio/project-2.jpeg'),
|
||||||
dates: [new Date('2022-08-02'), null],
|
dates: [new Date('2019-06'), new Date('2020-02')],
|
||||||
description: 'Freedom Scientific',
|
|
||||||
details: [
|
details: [
|
||||||
//{ label: 'Credential ID', value: 'TT-2208-03281' },
|
{ label: 'Team size', value: '7 people' },
|
||||||
// { label: 'Company', value: 'None' },
|
{ label: 'My role', value: ['Front-end Developer', 'Mobile Developer', 'Designer'] },
|
||||||
// { label: 'Category', value: ['Web app', 'Open source'] },
|
{ label: 'Company', value: 'Facebook' },
|
||||||
|
{ label: 'Category', value: ['Web app', 'Mobile app'] },
|
||||||
],
|
],
|
||||||
pdfDetails: [
|
pdfDetails: [
|
||||||
// { label: 'Demo', value: 'https://golden-bulls-d73jd7.netlify.app', url: '#' },
|
{ label: 'Demo', value: 'https://tru-quest-ck7ea3.netlify.app', url: '#' },
|
||||||
// { label: 'Repository', value: 'https://github.com/mark-freeman/golden-bulls', url: '#' },
|
{ label: 'Repository', value: 'https://github.com/mark-freeman/tru-quest', url: '#' },
|
||||||
],
|
],
|
||||||
screenshots: [
|
description:
|
||||||
{ src: import('@/assets/portfolio/jaws-certificate.png'), alt: 'JAWS Cerficiation' },
|
'Ut ultricies tortor at sodales aliquam. Vivamus metus ante, fringilla nec ligula in, suscipit rhoncus mauris. Praesent hendrerit velit odio, at accumsan urna faucibus convallis. Nunc at massa eget ligula volutpat dictum a sit amet libero. Vestibulum iaculis molestie maximus. In hac habitasse platea dictumst.',
|
||||||
// { src: import('@/assets/portfolio/project-1-screenshot-2.jpg'), alt: 'Second screenshot' },
|
|
||||||
// { src: import('@/assets/portfolio/project-1-screenshot-3.jpg'), alt: 'Third screenshot' },
|
|
||||||
],
|
|
||||||
//description: '',
|
|
||||||
// 'In tristique vulputate augue vel egestas. Quisque ac imperdiet tortor, at lacinia ex. Duis vel ex hendrerit, commodo odio sed, aliquam enim. Ut arcu nulla, tincidunt eget arcu eget, molestie vulputate nisi. Nunc malesuada leo et est iaculis facilisis.',
|
|
||||||
tagsList: {
|
tagsList: {
|
||||||
title: '', //'Technologies',
|
title: 'Technologies',
|
||||||
tags: [], //[nextJs(), sass(), pnpm(), eslint(), prettier()],
|
tags: [react(), tailwindCss(), nestJs(), postgreSql()],
|
||||||
},
|
},
|
||||||
links: [], //[mockups({ url: '#' }), demo({ url: '#' })],
|
links: [mockups({ url: '#' }), demo({ url: '#' })],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Software Chasers',
|
||||||
|
image: import('@/assets/portfolio/project-3.jpeg'),
|
||||||
|
dates: [new Date('2018-01'), new Date('2020-12')],
|
||||||
|
details: [
|
||||||
|
{ label: 'Team size', value: '3 people' },
|
||||||
|
{ label: 'My role', value: ['Front-end Developer', 'Designer'] },
|
||||||
|
{ label: 'Company', value: 'None' },
|
||||||
|
{ label: 'Category', value: ['Web app', 'Open source'] },
|
||||||
|
],
|
||||||
|
pdfDetails: [
|
||||||
|
{ label: 'Demo', value: 'https://software-chasers-e82l8e.netlify.app', url: '#' },
|
||||||
|
{ label: 'Repository', value: 'https://github.com/mark-freeman/software-chasers', url: '#' },
|
||||||
|
],
|
||||||
|
description:
|
||||||
|
'Quisque id consectetur eros. In hac habitasse platea dictumst. Sed eu pulvinar orci. Mauris consequat, est in dignissim varius, neque nisl commodo mauris, id blandit risus justo eu nulla.',
|
||||||
|
tagsList: {
|
||||||
|
title: 'Technologies',
|
||||||
|
tags: [react(), chakraUi(), typescript(), nx(), pnpm()],
|
||||||
|
},
|
||||||
|
links: [website({ url: '#' }), github({ url: '#' })],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Disco Ninjas',
|
||||||
|
image: import('@/assets/portfolio/project-4.jpeg'),
|
||||||
|
dates: [new Date('2016-05'), new Date('2018-07')],
|
||||||
|
details: [
|
||||||
|
{ label: 'Team size', value: '11 people' },
|
||||||
|
{ label: 'My role', value: 'Front-end Developer' },
|
||||||
|
{ label: 'Company', value: 'Google' },
|
||||||
|
{ label: 'Category', value: ['Mobile app', 'Open source'] },
|
||||||
|
],
|
||||||
|
pdfDetails: [
|
||||||
|
{ label: 'Demo', value: 'https://disco-ninjas-g321ol.netlify.app', url: '#' },
|
||||||
|
{ label: 'Repository', value: 'https://github.com/mark-freeman/disco-ninjas', url: '#' },
|
||||||
|
],
|
||||||
|
description:
|
||||||
|
'Praesent eu neque tortor. Vestibulum ac magna nisl. Vivamus massa sem, feugiat in pharetra non, convallis egestas purus. Ut consequat ullamcorper sem, in euismod nibh posuere ut. ',
|
||||||
|
tagsList: {
|
||||||
|
title: 'Technologies',
|
||||||
|
tags: [typescript(), jest(), firebase()],
|
||||||
|
},
|
||||||
|
links: [mockups({ url: '#' }), github({ url: '#' })],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
} as const satisfies ReadonlyDeep<PortfolioSection>;
|
} as const satisfies ReadonlyDeep<PortfolioSection>;
|
||||||
|
|
|
||||||
80
src/data/sections/skills-section.data.ts
Normal file
|
|
@ -0,0 +1,80 @@
|
||||||
|
import type { SkillsSection } from '@/types/sections/skills-section.types';
|
||||||
|
import type { ReadonlyDeep } from 'type-fest';
|
||||||
|
import {
|
||||||
|
apolloGraphql,
|
||||||
|
astro,
|
||||||
|
chakraUi,
|
||||||
|
cypress,
|
||||||
|
eslint,
|
||||||
|
firebase,
|
||||||
|
mongoDb,
|
||||||
|
nestJs,
|
||||||
|
pnpm,
|
||||||
|
postgreSql,
|
||||||
|
prettier,
|
||||||
|
react,
|
||||||
|
sass,
|
||||||
|
supabase,
|
||||||
|
tailwindCss,
|
||||||
|
typescript,
|
||||||
|
} from '../helpers/skills';
|
||||||
|
|
||||||
|
const skillsSectionData = {
|
||||||
|
config: {
|
||||||
|
title: 'Skills',
|
||||||
|
slug: 'skills',
|
||||||
|
icon: 'fa6-solid:bars-progress',
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
skillSets: [
|
||||||
|
{
|
||||||
|
title: 'I already know',
|
||||||
|
skills: [
|
||||||
|
react({
|
||||||
|
level: 5,
|
||||||
|
description:
|
||||||
|
'Proin ut erat sed massa tempus suscipit. Mauris efficitur nunc sem, nec scelerisque ligula bibendum ut.',
|
||||||
|
}),
|
||||||
|
typescript({
|
||||||
|
level: 4,
|
||||||
|
description: 'Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.',
|
||||||
|
}),
|
||||||
|
sass({
|
||||||
|
level: 4,
|
||||||
|
description: 'Nulla interdum pellentesque ultricies. Ut id eros commodo, ultrices ligula eu, elementum ante.',
|
||||||
|
}),
|
||||||
|
chakraUi({ level: 5 }),
|
||||||
|
tailwindCss({ level: 2 }),
|
||||||
|
prettier({ level: 5 }),
|
||||||
|
eslint({
|
||||||
|
level: 4,
|
||||||
|
description:
|
||||||
|
'Nulla tempor turpis at vehicula pharetra. Vestibulum tellus tortor, commodo et suscipit id, lobortis id nunc.',
|
||||||
|
}),
|
||||||
|
nestJs({
|
||||||
|
level: 2,
|
||||||
|
description:
|
||||||
|
'Praesent feugiat ultricies iaculis. In posuere vehicula odio, sed consequat velit porta viverra.',
|
||||||
|
}),
|
||||||
|
postgreSql({ level: 2 }),
|
||||||
|
mongoDb({ level: 1 }),
|
||||||
|
firebase({ level: 1 }),
|
||||||
|
pnpm({ level: 3 }),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'I want to learn',
|
||||||
|
skills: [apolloGraphql(), astro(), supabase(), cypress()],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'I speak',
|
||||||
|
skills: [
|
||||||
|
{ icon: 'circle-flags:pl', name: 'Polish - native' },
|
||||||
|
{ icon: 'circle-flags:us', name: 'English - C1' },
|
||||||
|
{ icon: 'circle-flags:es-variant', name: 'Spanish - B1' },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as const satisfies ReadonlyDeep<SkillsSection>;
|
||||||
|
|
||||||
|
export default skillsSectionData;
|
||||||
40
src/data/sections/testimonials-section.data.ts
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
import type { TestimonialsSection } from '@/types/sections/testimonials-section.types';
|
||||||
|
import type { ReadonlyDeep } from 'type-fest';
|
||||||
|
import { github, linkedin, website } from '../helpers/links';
|
||||||
|
|
||||||
|
const testimonialsSectionData = {
|
||||||
|
config: {
|
||||||
|
title: 'Testimonials',
|
||||||
|
slug: 'testimonials',
|
||||||
|
icon: 'fa6-solid:comment',
|
||||||
|
visible: true,
|
||||||
|
},
|
||||||
|
testimonials: [
|
||||||
|
{
|
||||||
|
image: import('@/assets/testimonials/testimonial-1.jpeg'),
|
||||||
|
author: 'Howard Stewart',
|
||||||
|
relation: 'We work together as front-end developers at Google',
|
||||||
|
content:
|
||||||
|
'In nec mattis sem. Morbi purus lorem, euismod ac varius at, aliquet vitae augue. Pellentesque ut facilisis felis. In sed dui blandit, aliquet odio eu, elementum leo. In facilisis dapibus tortor ac volutpat. Cras cursus nec odio maximus elementum.',
|
||||||
|
links: [github({ url: '#' }), linkedin({ url: '#' })],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: import('@/assets/testimonials/testimonial-2.jpeg'),
|
||||||
|
author: 'Jean Richards',
|
||||||
|
relation: 'My project manager at GitLab',
|
||||||
|
content:
|
||||||
|
'Praesent nec congue elit. Vestibulum lobortis congue ipsum, a gravida mi tempus ac. Mauris aliquet purus nibh, vel varius turpis tempus non. Nullam eget ultricies orci. Quisque nulla ante, auctor eget varius ac, imperdiet nec magna.',
|
||||||
|
links: [linkedin({ url: '#' })],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
image: import('@/assets/testimonials/testimonial-3.jpeg'),
|
||||||
|
author: 'Jason Fisher',
|
||||||
|
relation: 'My customer for sidewing.com website',
|
||||||
|
content:
|
||||||
|
'Mauris tincidunt at purus vehicula porta. Mauris eget mollis turpis. Sed iaculis rutrum pharetra. Vivamus risus quam, suscipit et semper ut, aliquet ut tellus. Donec quis auctor nunc.',
|
||||||
|
links: [github({ url: '#' }), website({ url: '#' })],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as const satisfies ReadonlyDeep<TestimonialsSection>;
|
||||||
|
|
||||||
|
export default testimonialsSectionData;
|
||||||
|
|
@ -18,16 +18,12 @@ const { config, sections } = cv();
|
||||||
<ThemeToggle />
|
<ThemeToggle />
|
||||||
<main class="w-full max-w-5xl space-y-4 px-2 py-3 sm:space-y-6 sm:px-8 sm:py-12 lg:space-y-8 lg:py-20">
|
<main class="w-full max-w-5xl space-y-4 px-2 py-3 sm:space-y-6 sm:px-8 sm:py-12 lg:space-y-8 lg:py-20">
|
||||||
<MainSection {...sections.main} />
|
<MainSection {...sections.main} />
|
||||||
<!--
|
|
||||||
<SkillsSection {...sections.skills} />
|
<SkillsSection {...sections.skills} />
|
||||||
-->
|
|
||||||
<ExperienceSection {...sections.experience} />
|
<ExperienceSection {...sections.experience} />
|
||||||
<PortfolioSection {...sections.portfolio} />
|
<PortfolioSection {...sections.portfolio} />
|
||||||
<EducationSection {...sections.education} />
|
<EducationSection {...sections.education} />
|
||||||
<!--
|
|
||||||
<TestimonialsSection {...sections.testimonials} />
|
<TestimonialsSection {...sections.testimonials} />
|
||||||
<FavoritesSection {...sections.favorites} />
|
<FavoritesSection {...sections.favorites} />
|
||||||
-->
|
|
||||||
</main>
|
</main>
|
||||||
<Sidebar sections={sections} className="sticky top-8 mt-20" />
|
<Sidebar sections={sections} className="sticky top-8 mt-20" />
|
||||||
<script src="../web/scripts/initialize-tooltips.ts"></script>
|
<script src="../web/scripts/initialize-tooltips.ts"></script>
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ const shouldRenderSection = (section: keyof typeof sections) => sections[section
|
||||||
</head>
|
</head>
|
||||||
<body class="flex flex-col bg-white p-[10mm] print:p-0">
|
<body class="flex flex-col bg-white p-[10mm] print:p-0">
|
||||||
{shouldRenderSection('main') && <MainSection {...sections.main} />}
|
{shouldRenderSection('main') && <MainSection {...sections.main} />}
|
||||||
<!-- {shouldRenderSection('skills') && <SkillsSection {...sections.skills} />} -->
|
{shouldRenderSection('skills') && <SkillsSection {...sections.skills} />}
|
||||||
{shouldRenderSection('experience') && <ExperienceSection {...sections.experience} />}
|
{shouldRenderSection('experience') && <ExperienceSection {...sections.experience} />}
|
||||||
{shouldRenderSection('portfolio') && <PortfolioSection {...sections.portfolio} />}
|
{shouldRenderSection('portfolio') && <PortfolioSection {...sections.portfolio} />}
|
||||||
{shouldRenderSection('education') && <EducationSection {...sections.education} />}
|
{shouldRenderSection('education') && <EducationSection {...sections.education} />}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
<div class="flex items-center gap-4 pb-5 pt-10">
|
<div class="flex items-center gap-4 pt-10 pb-5">
|
||||||
<div class="whitespace-nowrap text-2xl font-extrabold text-gray-900"><slot /></div>
|
<div class="whitespace-nowrap text-2xl font-extrabold text-gray-900"><slot /></div>
|
||||||
<hr class="w-full bg-gray-300" />
|
<hr class="w-full bg-gray-300" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ const { image, fullName, role, details, pdfDetails, description } = Astro.props;
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex gap-6">
|
<div class="flex gap-6">
|
||||||
<Photo src={image} alt={fullName} class="h-40 max-h-[160px] w-40 max-w-[160px] rounded-2xl" />
|
<Photo src={image} alt={fullName} class="w-40 h-40 max-w-[160px] max-h-[160px] rounded-2xl" />
|
||||||
<div>
|
<div>
|
||||||
<div class="text-3xl font-extrabold text-gray-900">{fullName}</div>
|
<div class="text-3xl font-extrabold text-gray-900">{fullName}</div>
|
||||||
<div class="text-lg font-medium text-gray-700">{role}</div>
|
<div class="text-lg font-medium text-gray-700">{role}</div>
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ const { config, skillSets } = Astro.props;
|
||||||
return (
|
return (
|
||||||
<div class="flex h-6 w-fit overflow-hidden rounded">
|
<div class="flex h-6 w-fit overflow-hidden rounded">
|
||||||
<div class="flex items-center bg-gray-100 pl-2.5 pr-2 font-medium">{skill.name}</div>
|
<div class="flex items-center bg-gray-100 pl-2.5 pr-2 font-medium">{skill.name}</div>
|
||||||
<div class="flex items-center bg-gray-200 pl-2 pr-2.5 font-normal">{skill.level}/5</div>
|
<div class="flex items-center bg-gray-200 pr-2.5 pl-2 font-normal">{skill.level}/5</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ const { config, skillSets } = Astro.props;
|
||||||
<div class="flex items-center bg-gray-100 pl-2.5 pr-2 font-medium">
|
<div class="flex items-center bg-gray-100 pl-2.5 pr-2 font-medium">
|
||||||
{skill.name.split(' - ')[0]}
|
{skill.name.split(' - ')[0]}
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center bg-gray-200 pl-2 pr-2.5 font-normal">
|
<div class="flex items-center bg-gray-200 pr-2.5 pl-2 font-normal">
|
||||||
{skill.name.split(' - ')[1]}
|
{skill.name.split(' - ')[1]}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ export interface LabelledValue {
|
||||||
value: string | string[];
|
value: string | string[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* URL that will be opened, when the value is clicked.
|
* URL that will be opened in a new tab, when the value is clicked.
|
||||||
*/
|
*/
|
||||||
url?: string;
|
url?: string;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ export interface Props extends DownloadButton {}
|
||||||
const { url, downloadedFileName, label } = Astro.props;
|
const { url, downloadedFileName, label } = Astro.props;
|
||||||
|
|
||||||
const classes = /* tw */ {
|
const classes = /* tw */ {
|
||||||
main: 'inline-flex items-center rounded-md shadow-sm bg-primary-600 select-none cursor-pointer text-base px-4 h-10 sm:text-sm sm:px-2 sm:h-8 lg:text-base lg:px-4 lg:h-10', // px-4 h-10',
|
main: 'inline-flex items-center px-4 h-10 rounded-md shadow-sm bg-primary-600 select-none cursor-pointer',
|
||||||
hover: 'hover:bg-primary-700',
|
hover: 'hover:bg-primary-700',
|
||||||
active: 'active:translate-y-px',
|
active: 'active:translate-y-px',
|
||||||
focus: 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500',
|
focus: 'focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500',
|
||||||
|
|
|
||||||
|
|
@ -7,16 +7,13 @@ export interface Props extends LabelledValue {}
|
||||||
const { label, value, url } = Astro.props;
|
const { label, value, url } = Astro.props;
|
||||||
|
|
||||||
const parsedValue = Array.isArray(value) ? value.join(', ') : value;
|
const parsedValue = Array.isArray(value) ? value.join(', ') : value;
|
||||||
|
|
||||||
const isHttpLink = url?.startsWith('http');
|
|
||||||
const target = isHttpLink ? '_blank' : '_self';
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="label">{label}:</Typography>
|
<Typography variant="label">{label}:</Typography>
|
||||||
{
|
{
|
||||||
url ? (
|
url ? (
|
||||||
<Typography as="a" href={url} target={target} class="no-underline">
|
<Typography as="a" href={url} target="_blank" class="underline">
|
||||||
{parsedValue}
|
{parsedValue}
|
||||||
</Typography>
|
</Typography>
|
||||||
) : (
|
) : (
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,11 @@ const { name, description, icon, iconColor, url } = Astro.props;
|
||||||
const className = /* tw */ 'flex h-6 w-fit items-center gap-x-1.5 rounded bg-gray-100 px-2.5 dark:bg-gray-700';
|
const className = /* tw */ 'flex h-6 w-fit items-center gap-x-1.5 rounded bg-gray-100 px-2.5 dark:bg-gray-700';
|
||||||
const customProps = url
|
const customProps = url
|
||||||
? ({
|
? ({
|
||||||
// href: url,
|
href: url,
|
||||||
as: 'span', //'a'
|
as: 'a',
|
||||||
// target: '_blank',
|
target: '_blank',
|
||||||
// rel: 'noopener noreferrer',
|
rel: 'noopener noreferrer',
|
||||||
class: `${className} hover:bg-gray-200 dark:hover:bg-gray-600 cursor-pointer`,
|
class: `${className} hover:bg-gray-200 dark:hover:bg-gray-600`,
|
||||||
} as const)
|
} as const)
|
||||||
: {
|
: {
|
||||||
class: className,
|
class: className,
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,11 @@ const variantToElement = {
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const variantToClassName: Record<TypographyVariant, string> /* tw */ = {
|
export const variantToClassName: Record<TypographyVariant, string> /* tw */ = {
|
||||||
'main-title': 'text-3xl sm:text-3xl font-bold text-gray-900 dark:text-gray-100',
|
'main-title': 'text-3xl sm:text-4xl font-extrabold text-gray-900 dark:text-gray-100',
|
||||||
'main-subtitle': 'text-base sm:text-lg font-medium text-gray-700 dark:text-gray-100',
|
'main-subtitle': 'text-base sm:text-lg font-medium text-gray-700 dark:text-gray-100',
|
||||||
'section-title': 'text-2xl font-bold text-gray-900 dark:text-gray-100', //text-3xl,
|
'section-title': 'text-3xl font-extrabold text-gray-900 dark:text-gray-100',
|
||||||
'section-subtitle': 'text-lg font-bold text-gray-900 dark:text-gray-100',
|
'section-subtitle': 'text-lg font-extrabold text-gray-900 dark:text-gray-100',
|
||||||
'item-title': 'text-lg font-bold text-gray-900 dark:text-gray-100', //text-xl',
|
'item-title': 'text-xl font-extrabold text-gray-900 dark:text-gray-100',
|
||||||
'item-subtitle-primary': 'text-base font-semibold leading-snug text-gray-900 dark:text-gray-100',
|
'item-subtitle-primary': 'text-base font-semibold leading-snug text-gray-900 dark:text-gray-100',
|
||||||
'item-subtitle-secondary': 'text-sm font-medium text-gray-700 dark:text-gray-100',
|
'item-subtitle-secondary': 'text-sm font-medium text-gray-700 dark:text-gray-100',
|
||||||
'tile-title': 'text-sm font-medium text-gray-700 dark:text-gray-200',
|
'tile-title': 'text-sm font-medium text-gray-700 dark:text-gray-200',
|
||||||
|
|
|
||||||
|
|
@ -21,23 +21,4 @@ const { meta, sections } = Astro.props;
|
||||||
<InitialHash sections={sections} />
|
<InitialHash sections={sections} />
|
||||||
<InitialTheme />
|
<InitialTheme />
|
||||||
<Fonts />
|
<Fonts />
|
||||||
|
|
||||||
<!-- Matomo -->
|
|
||||||
<script>
|
|
||||||
var _paq = window._paq = window._paq || [];
|
|
||||||
/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
|
|
||||||
_paq.push(["setCookieDomain", "*.juyoun.gg"]);
|
|
||||||
_paq.push(['trackPageView']);
|
|
||||||
_paq.push(['enableLinkTracking']);
|
|
||||||
(function() {
|
|
||||||
var u="//radar.juyoun.gg/";
|
|
||||||
_paq.push(['setTrackerUrl', u+'matomo.php']);
|
|
||||||
_paq.push(['setSiteId', '1']);
|
|
||||||
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
|
|
||||||
g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
|
|
||||||
})();
|
|
||||||
</script>
|
|
||||||
<noscript><p><img referrerpolicy="no-referrer-when-downgrade" src="//radar.juyoun.gg/matomo.php?idsite=1&rec=1" style="border:0;" alt="" /></p></noscript>
|
|
||||||
<!-- End Matomo Code -->
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,8 @@ const { title, institution, dates, description, links, image } = Astro.props;
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col">
|
||||||
<Typography variant="item-title">{title}</Typography>
|
<Typography variant="item-title">{title}</Typography>
|
||||||
<Typography variant="item-subtitle-primary" class="mb-0.5">{institution}</Typography>
|
<Typography variant="item-subtitle-primary" class="mb-0.5">{institution}</Typography>
|
||||||
<!-- <Timestamp dates={dates} /> -->
|
<Timestamp dates={dates} />
|
||||||
<Typography variant="item-subtitle-secondary" class="mb-0.5">{description}</Typography>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
{
|
{
|
||||||
links.length > 0 && (
|
links.length > 0 && (
|
||||||
|
|
@ -32,5 +31,5 @@ const { title, institution, dates, description, links, image } = Astro.props;
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<!--<Description content={description} /> -->
|
<Description content={description} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const { image, title, type, url } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Photo class="aspect-square rounded-lg object-cover shadow-md" src={image} alt={title} width={200} height={200} />
|
<Photo class="rounded-lg shadow-md aspect-square object-cover" src={image} alt={title} width={200} height={200} />
|
||||||
<div class="gap-1">
|
<div class="gap-1">
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{title}
|
{title}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ const { image, name, url } = Astro.props;
|
||||||
|
|
||||||
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Photo
|
<Photo
|
||||||
class="aspect-square rounded-lg object-cover shadow-md transition duration-300"
|
class="rounded-lg shadow-md transition duration-300 aspect-square object-cover"
|
||||||
src={image}
|
src={image}
|
||||||
alt={name}
|
alt={name}
|
||||||
width={200}
|
width={200}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ const { title, url, image } = Astro.props;
|
||||||
---
|
---
|
||||||
|
|
||||||
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
<a href={url} target="_blank" class="flex w-full flex-col gap-3 transition duration-300 hover:translate-y-2">
|
||||||
<Photo class="aspect-video rounded-lg object-cover shadow-md" src={image} alt={title} width={480} height={270} />
|
<Photo class="rounded-lg shadow-md aspect-video object-cover" src={image} alt={title} width={480} height={270} />
|
||||||
<Typography variant="tile-title">
|
<Typography variant="tile-title">
|
||||||
{title}
|
{title}
|
||||||
</Typography>
|
</Typography>
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ const { action, config, description, details, fullName, image, links, role, tags
|
||||||
alt={fullName}
|
alt={fullName}
|
||||||
width={320}
|
width={320}
|
||||||
height={320}
|
height={320}
|
||||||
class="h-24 w-24 max-w-none rounded-lg sm:h-36 sm:w-36 md:h-52 md:w-52"
|
class="w-24 h-24 sm:w-36 sm:h-36 md:w-52 md:h-52 rounded-lg max-w-none"
|
||||||
/>
|
/>
|
||||||
<!--<DownloadButton {...action} />-->
|
<DownloadButton {...action} />
|
||||||
</div>
|
</div>
|
||||||
<div class="flex w-full flex-col gap-5">
|
<div class="flex w-full flex-col gap-5">
|
||||||
<div class="flex w-full flex-col justify-between gap-2 sm:flex-row">
|
<div class="flex w-full flex-col justify-between gap-2 sm:flex-row">
|
||||||
|
|
|
||||||
|
|
@ -24,20 +24,16 @@ const screenshotsIcon = screenshotsConfig?.icon || 'fa6-solid:image';
|
||||||
const screenshotsTooltip = screenshotsConfig?.title || 'Screenshots';
|
const screenshotsTooltip = screenshotsConfig?.title || 'Screenshots';
|
||||||
---
|
---
|
||||||
|
|
||||||
<div class="flex flex-col">
|
<div class="flex flex-col gap-6">
|
||||||
<!-- gap-6">-->
|
<div class="flex flex-col gap-4">
|
||||||
<div class="flex flex-col">
|
<div class="flex gap-6">
|
||||||
<!-- gap-4">-->
|
|
||||||
<div class="flex">
|
|
||||||
<!-- gap-6">-->
|
|
||||||
<div class="flex w-full flex-col gap-4">
|
<div class="flex w-full flex-col gap-4">
|
||||||
<div class="flex gap-4">
|
<div class="flex gap-4">
|
||||||
<Thumbnail src={image} alt={alt} size="small" />
|
<Thumbnail src={image} alt={alt} size="small" />
|
||||||
<div class="flex w-full justify-between">
|
<div class="flex w-full justify-between">
|
||||||
<div>
|
<div>
|
||||||
<Typography variant="item-title">{name}</Typography>
|
<Typography variant="item-title">{name}</Typography>
|
||||||
<!--<Timestamp dates={dates} />-->
|
<Timestamp dates={dates} />
|
||||||
<Typography variant="item-subtitle-secondary">{description}</Typography>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex gap-2">
|
<div class="flex gap-2">
|
||||||
{links.map((link) => <LinkButton {...link} />)}
|
{links.map((link) => <LinkButton {...link} />)}
|
||||||
|
|
@ -54,7 +50,7 @@ const screenshotsTooltip = screenshotsConfig?.title || 'Screenshots';
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!--<Description content={description} class="col-span-3 col-start-1" /> -->
|
<Description content={description} class="col-span-3 col-start-1" />
|
||||||
</div>
|
</div>
|
||||||
<TagsList {...tagsList} />
|
<TagsList {...tagsList} />
|
||||||
<div class="hidden" id={galleryId}>
|
<div class="hidden" id={galleryId}>
|
||||||
|
|
|
||||||
29
src/web/sections/skills/levelled-skill.astro
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
---
|
||||||
|
import type { LevelledSkill } from '@/types/sections/skills-section.types';
|
||||||
|
import Icon from '@/web/components/icon.astro';
|
||||||
|
import Typography from '@/web/components/typography.astro';
|
||||||
|
import SkillLevel from './skill-level.astro';
|
||||||
|
|
||||||
|
export interface Props extends LevelledSkill {}
|
||||||
|
|
||||||
|
const { url, icon, iconColor, name, level, description } = Astro.props;
|
||||||
|
|
||||||
|
const IconWrapper = url ? 'a' : 'div';
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-2">
|
||||||
|
<div class="flex h-5 items-center justify-between">
|
||||||
|
<IconWrapper class="flex gap-2 h-5" {...url && { href: url, target: '_blank', rel: 'noopener noreferrer' }}>
|
||||||
|
{icon && <Icon name={icon} color={iconColor} size={20} />}
|
||||||
|
<Typography variant="skill">{name}</Typography>
|
||||||
|
</IconWrapper>
|
||||||
|
{
|
||||||
|
description && (
|
||||||
|
<div class="flex h-3.5 w-3.5" data-tooltip={description} data-tooltip-placement="top">
|
||||||
|
<Icon name="fa6-solid:circle-info" color="#D1D5DB" size={14} />
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<SkillLevel skillLevel={level} />
|
||||||
|
</div>
|
||||||
24
src/web/sections/skills/skill-level-tile.astro
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
---
|
||||||
|
import type { SkillLevel } from '@/types/sections/skills-section.types';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
skillLevel: SkillLevel;
|
||||||
|
tileLevel: SkillLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { skillLevel, tileLevel } = Astro.props;
|
||||||
|
|
||||||
|
const isFilled = skillLevel >= tileLevel;
|
||||||
|
const classes = /* tw */ {
|
||||||
|
filled: 'bg-gray-500 dark:bg-gray-300',
|
||||||
|
empty: 'bg-gray-200 dark:bg-gray-500',
|
||||||
|
};
|
||||||
|
---
|
||||||
|
|
||||||
|
<div
|
||||||
|
class:list={[
|
||||||
|
'w-9 h-2 last:rounded-l-none last:rounded-r-sm first:rounded-l-sm first:rounded-r-none',
|
||||||
|
isFilled ? classes.filled : classes.empty,
|
||||||
|
]}
|
||||||
|
>
|
||||||
|
</div>
|
||||||
16
src/web/sections/skills/skill-level.astro
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
---
|
||||||
|
import type { SkillLevel } from '@/types/sections/skills-section.types';
|
||||||
|
import SkillLevelTile from './skill-level-tile.astro';
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
skillLevel: SkillLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { skillLevel } = Astro.props;
|
||||||
|
|
||||||
|
const levels = [1, 2, 3, 4, 5] as const;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex gap-1">
|
||||||
|
{levels.map((tileLevel) => <SkillLevelTile tileLevel={tileLevel} skillLevel={skillLevel} />)}
|
||||||
|
</div>
|
||||||
32
src/web/sections/skills/skill-set.astro
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
---
|
||||||
|
import type { LevelledSkill as LevelledSkillType, SkillSet } from '@/types/sections/skills-section.types';
|
||||||
|
import TagsList from '@/web/components/tags-list.astro';
|
||||||
|
import Typography from '@/web/components/typography.astro';
|
||||||
|
import LevelledSkill from './levelled-skill.astro';
|
||||||
|
|
||||||
|
export interface Props extends SkillSet {}
|
||||||
|
|
||||||
|
const { skills, title } = Astro.props;
|
||||||
|
|
||||||
|
const isLevelledSkillSection = (skills: Props['skills']): skills is LevelledSkillType[] => {
|
||||||
|
const firstSkill = skills[0];
|
||||||
|
if (!firstSkill) return false;
|
||||||
|
|
||||||
|
return 'level' in firstSkill && firstSkill.level !== undefined;
|
||||||
|
};
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex flex-col gap-3">
|
||||||
|
<Typography variant="section-subtitle">{title}</Typography>
|
||||||
|
{
|
||||||
|
isLevelledSkillSection(skills) ? (
|
||||||
|
<div class="flex flex-wrap gap-8">
|
||||||
|
{skills.map((skill) => (
|
||||||
|
<LevelledSkill {...skill} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<TagsList tags={skills} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
15
src/web/sections/skills/skills-section.web.astro
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
---
|
||||||
|
import type { SkillsSection } from '@/types/sections/skills-section.types';
|
||||||
|
import SectionCard from '@/web/components/section-card.astro';
|
||||||
|
import SkillSet from './skill-set.astro';
|
||||||
|
|
||||||
|
export interface Props extends SkillsSection {}
|
||||||
|
|
||||||
|
const { config, skillSets } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<SectionCard {...config}>
|
||||||
|
<div class="flex flex-col gap-10">
|
||||||
|
{skillSets.map((skillSet) => <SkillSet {...skillSet} />)}
|
||||||
|
</div>
|
||||||
|
</SectionCard>
|
||||||
33
src/web/sections/testimonials/testimonial.astro
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
---
|
||||||
|
import type { Testimonial } from '@/types/sections/testimonials-section.types';
|
||||||
|
import LinkButton from '@/web/components/link-button.astro';
|
||||||
|
import Typography from '@/web/components/typography.astro';
|
||||||
|
import Description from '@/web/components/description.astro';
|
||||||
|
import Thumbnail from '@/web/components/thumbnail.astro';
|
||||||
|
|
||||||
|
export interface Props extends Testimonial {}
|
||||||
|
|
||||||
|
const { author, content, image, links, relation } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class="flex w-full flex-col gap-4">
|
||||||
|
<div class="flex justify-between">
|
||||||
|
<div class="flex flex-col gap-4 sm:flex-row">
|
||||||
|
<Thumbnail src={image} alt={author} size="small" />
|
||||||
|
<div>
|
||||||
|
<Typography variant="item-title">{author}</Typography>
|
||||||
|
<Typography variant="item-subtitle-secondary">{relation}</Typography>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{
|
||||||
|
links.length > 0 && (
|
||||||
|
<div class="flex gap-3">
|
||||||
|
{links.map((link) => (
|
||||||
|
<LinkButton {...link} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<Description content={content} />
|
||||||
|
</div>
|
||||||
17
src/web/sections/testimonials/testimonials-section.web.astro
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
import type { TestimonialsSection } from '@/types/sections/testimonials-section.types';
|
||||||
|
import DividedList from '@/web/components/divided-list.astro';
|
||||||
|
import Divider from '@/web/components/divider.astro';
|
||||||
|
import SectionCard from '@/web/components/section-card.astro';
|
||||||
|
import Testimonial from './testimonial.astro';
|
||||||
|
|
||||||
|
export interface Props extends TestimonialsSection {}
|
||||||
|
|
||||||
|
const { testimonials, config } = Astro.props;
|
||||||
|
---
|
||||||
|
|
||||||
|
<SectionCard {...config}>
|
||||||
|
<DividedList>
|
||||||
|
{testimonials.flatMap((testimonial) => [<Testimonial {...testimonial} />, <Divider />])}
|
||||||
|
</DividedList>
|
||||||
|
</SectionCard>
|
||||||
|
|
@ -10,7 +10,7 @@ module.exports = {
|
||||||
transparent: 'transparent',
|
transparent: 'transparent',
|
||||||
current: 'currentColor',
|
current: 'currentColor',
|
||||||
white: colors.white,
|
white: colors.white,
|
||||||
primary: colors.blue,
|
primary: colors.indigo,
|
||||||
gray: colors.gray,
|
gray: colors.gray,
|
||||||
},
|
},
|
||||||
extend: {
|
extend: {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,8 @@
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
// Enable strict type checking.
|
// Enable strict type checking.
|
||||||
"strict": true,
|
"strict": true,
|
||||||
|
// Error when a value import is only used as a type.
|
||||||
|
"importsNotUsedAsValues": "error",
|
||||||
// Report errors for fallthrough cases in switch statements
|
// Report errors for fallthrough cases in switch statements
|
||||||
"noFallthroughCasesInSwitch": true,
|
"noFallthroughCasesInSwitch": true,
|
||||||
// Force functions designed to override their parent class to be specified as `override`.
|
// Force functions designed to override their parent class to be specified as `override`.
|
||||||
|
|
|
||||||