Initial commit

This commit is contained in:
2026-01-15 12:44:09 +02:00
commit 05bcfc12d2
46 changed files with 2157 additions and 0 deletions

1
.env.production Normal file
View File

@@ -0,0 +1 @@
DISABLE_ESLINT_PLUGIN=true

View File

@@ -0,0 +1,62 @@
name: Build
on:
workflow_dispatch:
inputs:
branch:
description: 'Branch to build'
required: true
default: 'main'
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Checkout branch
uses: actions/checkout@v3
with:
ref: ${{ gitea.event.inputs.branch }}
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 24
- name: Install dependencies
run: |
set -euo pipefail
npm install --no-audit --silent 2>&1 | tee install.log
env:
NODE_OPTIONS: '--max-old-space-size=4096'
- name: Build (react-scripts build)
env:
CI: 'false'
NODE_OPTIONS: '--max-old-space-size=4096'
run: |
set -euo pipefail
npm run build 2>&1 | tee build.log
timeout-minutes: 5
- name: Verify build folder exists
run: test -d build || (echo "No build folder. Check build logs above."; exit 1)
- name: Upload logs on failure
if: failure()
uses: actions/upload-artifact@v3
with:
name: build-logs
path: |
install.log
build.log
npm-debug.log*
if-no-files-found: ignore
- name: Build completed
if: success()
run: echo "Build completed successfully"

41
package.json Normal file
View File

@@ -0,0 +1,41 @@
{
"name": "nestjs-jobs",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-scripts": "^5.0.1",
"framer-motion": "^11.0.0",
"lucide-react": "^0.400.0"
},
"devDependencies": {
"tailwindcss": "^3.4.0",
"postcss": "^8.4.0",
"autoprefixer": "^10.4.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

6
postcss.config.js Normal file
View File

@@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
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

View File

@@ -0,0 +1 @@
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

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMS40MTQiPjxwYXRoIGZpbGw9IiMzMzMiIGQ9Ik00OS43MzUgNTguMzVhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtMTkuNjgyIDBhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtLTQ1LjYyNiAwYTQuODIyIDQuODIyIDAgMCAxIDQuODM4LTQuODM4IDQuODIyIDQuODIyIDAgMCAxIDQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM4LTQuODM4bS0xOS42ODIgMGE0LjgyMiA0LjgyMiAwIDAgMSA0LjgzNy00LjgzOCA0LjgyMiA0LjgyMiAwIDAgMSA0LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzNy00LjgzOG0zOS43OTQtOC41NDloLTQuMjA4djE2LjkzMmg0LjIwOFY0OS44MDF6TTEzLjc1MSA2Ni43MzNoNC4yMDhWNDkuODAxaC00LjIwOHYxLjM1OWE4LjY5OCA4LjY5OCAwIDAgMC01LjAwMy0xLjU1N0E4LjczOSA4LjczOSAwIDAgMCAwIDU4LjM1YTguNzE4IDguNzE4IDAgMCAwIDguNzQ4IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem02NS4zMDggMGg0LjIwOFY0OS44MDFoLTQuMjA4djEuMzU5YTguNjk4IDguNjk4IDAgMCAwLTUuMDAzLTEuNTU3IDguNzM4IDguNzM4IDAgMCAwLTguNzQ3IDguNzQ3IDguNzE3IDguNzE3IDAgMCAwIDguNzQ3IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem01Ljc2Ni01LjUwMWMuMTMyIDMuNDEzIDMuMDQ4IDUuODMyIDcuOTE5IDUuODMyIDMuOTc2IDAgNy4yNTYtMS43MjMgNy4yNTYtNS41MzMgMC0yLjY1MS0xLjQ5MS00LjIwOC00LjkzNy00Ljg3MWwtMi42ODQtLjUzYy0xLjcyMy0uMzMxLTIuOTE2LS42NjMtMi45MTYtMS42OSAwLTEuMTI2IDEuMTYtMS42MjMgMi42MTgtMS42MjMgMi4xMjEgMCAyLjk4MiAxLjA2IDMuMDQ4IDIuMzE5aDQuMjQyYy0uMjMyLTMuMzE0LTIuODgzLTUuNTMzLTcuMTU3LTUuNTMzLTQuNDA3IDAtNy4wMjUgMi40MTgtNy4wMjUgNS41NjYgMCAzLjg0NCAzLjExNSA0LjQ3MyA1Ljc5OSA0Ljk3bDIuMjIuMzk4YzEuNTkuMjk4IDIuMjg2Ljc2MiAyLjI4NiAxLjY5IDAgLjgyOC0uNzk1IDEuNjU2LTIuNjg0IDEuNjU2LTIuNzUgMC0zLjY0NS0xLjQyNC0zLjY3OC0yLjY1MWgtNC4zMDd6TTMzLjQzMyA0NC4wMzZ2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzkgOC43MzkgMCAwIDAtOC43NDggOC43NDcgOC43MTggOC43MTggMCAwIDAgOC43NDggOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptMjUuOTQ0IDB2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzggOC43MzggMCAwIDAtOC43NDcgOC43NDcgOC43MTcgOC43MTcgMCAwIDAgOC43NDcgOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptLTQ4LjQ0My01LjAwM2wyLjg1IDUuMDAzaDE5LjY0OWwtNy43ODctMTMuNDUzLTE0LjcxMiA4LjQ1em0zMi45NjkgOS4yMTF2LTQuMjA4aDE1LjQ3NEw0Mi44NzYgMTUuNDc0bC0xNC43NDUgOC40NDkgMTEuNTY0IDIwLjExM3Y0LjIwOGg0LjIwOHptMjEuNzM3LTQuMjA4aDE5LjY4Mkw1OS44NzQgMCA0NS4xNjMgOC40ODIgNjUuNjQgNDQuMDM2eiIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9zdmc+

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04IiAvPgogICAgPGxpbmsgcmVsPSJpY29uIiBocmVmPSIvZmF2aWNvbi5pY28iIC8+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEiIC8+CiAgICA8bWV0YSBuYW1lPSJ0aGVtZS1jb2xvciIgY29udGVudD0iIzE1MTkyNCIgLz4KICAgIDxtZXRhCiAgICAgIG5hbWU9ImRlc2NyaXB0aW9uIgogICAgICBjb250ZW50PSJOZXN0SlMgam9icyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaXJlIG9yIGdldCBoaXJlZCBhcyBOZXN0SlMgZGV2ZWxvcGVyLiBGaW5kIE5lc3RKUyB0YWxlbnQgYW5kIHJlYWNoIHRvIHRob3VzYW5kcyBvZiBkZXZlbG9wZXJzLiIKICAgIC8+CiAgICA8bWV0YSBuYW1lPSJyb2JvdHMiIGNvbnRlbnQ9Im5vb2RwIiAvPgogICAgPGxpbmsgcmVsPSJjYW5vbmljYWwiIGhyZWY9Imh0dHBzOi8vam9icy5uZXN0anMuY29tIiAvPgogICAgPG1ldGEgcHJvcGVydHk9Im9nOnVybCIgY29udGVudD0iaHR0cHM6Ly9qb2JzLm5lc3Rqcy5jb20iIC8+CiAgICA8bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2UiIGNvbnRlbnQ9Imh0dHBzOi8vbmVzdGpzLmNvbS9pbWcvbmVzdC1vZy5wbmciPgogICAgPG1ldGEgcHJvcGVydHk9Im9nOnR5cGUiIGNvbnRlbnQ9IndlYnNpdGUiIC8+CiAgICA8bWV0YSBuYW1lPSJ0d2l0dGVyOmNhcmQiIGNvbnRlbnQ9InN1bW1hcnlfbGFyZ2VfaW1hZ2UiIC8+CiAgICA8bWV0YQogICAgICBwcm9wZXJ0eT0ib2c6c2l0ZV9uYW1lIgogICAgICBjb250ZW50PSJKb2JzIHwgTmVzdEpTIC0gQSBwcm9ncmVzc2l2ZSBOb2RlLmpzIGZyYW1ld29yayIKICAgIC8+CiAgICA8bWV0YQogICAgICBwcm9wZXJ0eT0ib2c6dGl0bGUiCiAgICAgIGNvbnRlbnQ9IkpvYnMgfCBOZXN0SlMgLSBBIHByb2dyZXNzaXZlIE5vZGUuanMgZnJhbWV3b3JrIgogICAgLz4KICAgIDxtZXRhCiAgICAgIHByb3BlcnR5PSJvZzpkZXNjcmlwdGlvbiIKICAgICAgY29udGVudD0iTmVzdEpTIGpvYnMgaXMgdGhlIGJlc3QgcGxhY2UgdG8gaGlyZSBvciBnZXQgaGlyZWQgYXMgTmVzdEpTIGRldmVsb3Blci4gRmluZCBOZXN0SlMgdGFsZW50IGFuZCByZWFjaCB0byB0aG91c2FuZHMgb2YgZGV2ZWxvcGVycy4iCiAgICAvPgogICAgPG1ldGEKICAgICAgbmFtZT0idHdpdHRlcjp0aXRsZSIKICAgICAgY29udGVudD0iSm9icyB8IE5lc3RKUyAtIEEgcHJvZ3Jlc3NpdmUgTm9kZS5qcyBmcmFtZXdvcmsiCiAgICAvPgogICAgPG1ldGEKICAgICAgbmFtZT0idHdpdHRlcjpkZXNjcmlwdGlvbiIKICAgICAgY29udGVudD0iTmVzdEpTIGpvYnMgaXMgdGhlIGJlc3QgcGxhY2UgdG8gaGlyZSBvciBnZXQgaGlyZWQgYXMgTmVzdEpTIGRldmVsb3Blci4gRmluZCBOZXN0SlMgdGFsZW50IGFuZCByZWFjaCB0byB0aG91c2FuZHMgb2YgZGV2ZWxvcGVycy4iCiAgICAvPgogICAgPGxpbmsgcmVsPSJwcmVjb25uZWN0IiBocmVmPSJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tIj4KICAgIDxsaW5rIHJlbD0icHJlY29ubmVjdCIgaHJlZj0iaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbSIgY3Jvc3NvcmlnaW4+CiAgICA8bGluayBocmVmPSJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9TW9udHNlcnJhdDozMDAsNDAwLDUwMCw2MDAsNzAwJmRpc3BsYXk9c3dhcCIgcmVsPSJzdHlsZXNoZWV0IiAvPgogICAgPGxpbmsgcmVsPSJhcHBsZS10b3VjaC1pY29uIiBocmVmPSIvbG9nbzE5Mi5wbmciIC8+CiAgICA8bGluayByZWw9Im1hbmlmZXN0IiBocmVmPSIvbWFuaWZlc3QuanNvbiIgLz4KICAgIDxsaW5rIHJlbD0ibWFzay1pY29uIiBocmVmPSIvaW1nL3NhZmFyaS1waW5uZWQtdGFiLnN2ZyIgY29sb3I9IiNlZDI5NDUiIC8+CiAgICA8c2NyaXB0IGRlZmVyIHNyYz0iaHR0cHM6Ly91c2UuZm9udGF3ZXNvbWUuY29tL3JlbGVhc2VzL3Y2LjQuMi9qcy9hbGwuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdD4KICAgICAgd2luZG93LmRhdGFMYXllciA9IHdpbmRvdy5kYXRhTGF5ZXIgfHwgW107CiAgICAgIGZ1bmN0aW9uIGd0YWcoKXtkYXRhTGF5ZXIucHVzaChhcmd1bWVudHMpO30KICAgICAgZ3RhZygnanMnLCBuZXcgRGF0ZSgpKTsKCiAgICAgIGd0YWcoJ2NvbmZpZycsICdHLVpFM1NHU0dWMjMnKTsKICAgIDwvc2NyaXB0PgogICAgPHRpdGxlPkpvYnMgfCBOZXN0SlMgLSBBIHByb2dyZXNzaXZlIE5vZGUuanMgZnJhbWV3b3JrPC90aXRsZT4KICAgIDxzY3JpcHQgdHlwZT0ibW9kdWxlIiBjcm9zc29yaWdpbiBzcmM9Ii9hc3NldHMvaW5kZXgtRGhyT0wxUzYuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBjcm9zc29yaWdpbiBocmVmPSIvYXNzZXRzL2luZGV4LURFYVhzblhXLmNzcyI+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPG5vc2NyaXB0PllvdSBuZWVkIHRvIGVuYWJsZSBKYXZhU2NyaXB0IHRvIHJ1biB0aGlzIGFwcC48L25vc2NyaXB0PgogICAgPGRpdiBpZD0icm9vdCI+PC9kaXY+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==

View File

@@ -0,0 +1 @@
PHN2ZyBoZWlnaHQ9IjE4MCIgdmlld0JveD0iMCAwIDE4MCAxODAiIHdpZHRoPSIxODAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiPjxsaW5lYXJHcmFkaWVudCBpZD0iYSIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIzMi42NCIgeDI9IjgyLjc3IiB5MT0iNjEuMTYiIHkyPSI4NS41NCI+PHN0b3Agb2Zmc2V0PSIuMjEiIHN0b3AtY29sb3I9IiNmZTI4NTciLz48c3RvcCBvZmZzZXQ9IjEiIHN0b3AtY29sb3I9IiMyOTM4OTYiLz48L2xpbmVhckdyYWRpZW50PjxsaW5lYXJHcmFkaWVudCBpZD0iYiIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiIHgxPSIxNy4zOCIgeDI9IjgyLjk1IiB5MT0iNjkuODYiIHkyPSIyMS4yMyI+PHN0b3Agb2Zmc2V0PSIwIiBzdG9wLWNvbG9yPSIjZmUyODU3Ii8+PHN0b3Agb2Zmc2V0PSIuMDEiIHN0b3AtY29sb3I9IiNmZTI4NTciLz48c3RvcCBvZmZzZXQ9Ii44NiIgc3RvcC1jb2xvcj0iI2ZmMzE4YyIvPjwvbGluZWFyR3JhZGllbnQ+PGxpbmVhckdyYWRpZW50IGlkPSJjIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9Ijc0LjE3IiB4Mj0iMTYwLjI3IiB5MT0iMjEuNTgiIHkyPSI5OS43NiI+PHN0b3Agb2Zmc2V0PSIuMDIiIHN0b3AtY29sb3I9IiNmZjMxOGMiLz48c3RvcCBvZmZzZXQ9Ii4yMSIgc3RvcC1jb2xvcj0iI2ZlMjg1NyIvPjxzdG9wIG9mZnNldD0iLjg2IiBzdG9wLWNvbG9yPSIjZmRiNjBkIi8+PC9saW5lYXJHcmFkaWVudD48bGluZWFyR3JhZGllbnQgaWQ9ImQiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4MT0iMTU1LjQ2IiB4Mj0iNTUuMDciIHkxPSI4OS44IiB5Mj0iMTU4LjkiPjxzdG9wIG9mZnNldD0iLjAxIiBzdG9wLWNvbG9yPSIjZmRiNjBkIi8+PHN0b3Agb2Zmc2V0PSIuODYiIHN0b3AtY29sb3I9IiNmY2Y4NGEiLz48L2xpbmVhckdyYWRpZW50PjxwYXRoIGQ9Im04MS41NiA4My43MS00MS4zNS0zNWExNSAxNSAwIDEgMCAtMTQuNDcgMjUuN2guMTVsLjM5LjEyIDUyLjE2IDE1Ljg5YTMuNTMgMy41MyAwIDAgMCAxLjE4LjIxIDMuNzMgMy43MyAwIDAgMCAxLjkzLTYuOTF6IiBmaWxsPSJ1cmwoI2EpIi8+PHBhdGggZD0ibTg5Ljg1IDI1LjkzYTEwLjg5IDEwLjg5IDAgMCAwIC0xNi44NS05LjE4bC01MC41IDMwLjY2YTE1IDE1IDAgMSAwIDE3LjkgMjRsNDUuMjctMzYuODkuMzYtLjNhMTAuOTMgMTAuOTMgMCAwIDAgMy44Mi04LjI5eiIgZmlsbD0idXJsKCNiKSIvPjxwYXRoIGQ9Im0xNjMuMjkgOTItNzYuNjItNzMuNzlhMTAuOTEgMTAuOTEgMCAxIDAgLTE0LjgxIDE2bC4xNC4xMiA4MS40IDY4LjU4YTcuMzYgNy4zNiAwIDAgMCAxMi4wOS01LjY1IDcuMzkgNy4zOSAwIDAgMCAtMi4yLTUuMjZ6IiBmaWxsPSJ1cmwoI2MpIi8+PHBhdGggZD0ibTE2NS41IDk3LjI5YTcuMzUgNy4zNSAwIDAgMCAtMTEuNjctNmwtOTIuNzEgNDUuM2ExNSAxNSAwIDEgMCAxNS40OCAyNS41OWw4NS43My01OC44NGE3LjM1IDcuMzUgMCAwIDAgMy4xNy02LjA1eiIgZmlsbD0idXJsKCNkKSIvPjxwYXRoIGQ9Im02MCA2MGg2MHY2MGgtNjB6Ii8+PGcgZmlsbD0iI2ZmZiI+PHBhdGggZD0ibTY2LjUzIDEwOC43NWgyMi41djMuNzVoLTIyLjV6Ii8+PHBhdGggZD0ibTY1LjU5IDc1LjQ3IDEuNjctMS41OGExLjg4IDEuODggMCAwIDAgMS40Ny44N2MuNjQgMCAxLjA2LS40NSAxLjA2LTEuMzJ2LTUuOTJoMi41OHY1Ljk0YTMuNDQgMy40NCAwIDAgMSAtLjkyIDIuNjMgMy41MiAzLjUyIDAgMCAxIC0yLjU3IDEgMy44NCAzLjg0IDAgMCAxIC0zLjI5LTEuNjJ6Ii8+PHBhdGggZD0ibTczLjUzIDY3LjUyaDcuNTN2Mi4xOWgtNXYxLjQzaDQuNDl2MmgtNC40NXYxLjQ5aDV2Mi4yaC03LjZ6Ii8+PHBhdGggZD0ibTg0LjczIDY5Ljc5aC0yLjh2LTIuMjdoOC4yMXYyLjI3aC0yLjgxdjcuMDloLTIuNnoiLz48cGF0aCBkPSJtNjYuNjMgODAuNThoNC40MmEzLjQ3IDMuNDcgMCAwIDEgMi41NS44MyAyLjA5IDIuMDkgMCAwIDEgLjYxIDEuNTIgMi4xOCAyLjE4IDAgMCAxIC0xLjQ1IDIuMDkgMi4yNyAyLjI3IDAgMCAxIDEuODYgMi4yOWMwIDEuNjktMS4zMSAyLjY5LTMuNTUgMi42OWgtNC40NHptNSAyLjg5YzAtLjUyLS40Mi0uOC0xLjE4LS44aC0xLjI5djEuNjRoMS4yNWMuNzggMCAxLjI0LS4yNyAxLjI0LS44MXptLS45IDIuNjZoLTEuNTd2MS43M2gxLjYyYy44IDAgMS4yNC0uMzEgMS4yNC0uODYtLjAyLS41My0uNC0uODctMS4yNy0uODd6Ii8+PHBhdGggZD0ibTc1LjQ1IDgwLjU4aDQuMTVhNC4xNCA0LjE0IDAgMCAxIDMuMDUgMSAyLjkyIDIuOTIgMCAwIDEgLjgzIDIuMTggMyAzIDAgMCAxIC0xLjkzIDIuODlsMi4yNCAzLjM1aC0zbC0xLjg5LTIuODRoLS44N3YyLjg0aC0yLjZ6bTQgNC41Yy44NyAwIDEuNC0uNDMgMS40LTEuMTIgMC0uNzUtLjU1LTEuMTMtMS40MS0xLjEzaC0xLjM5djIuMjd6Ii8+PHBhdGggZD0ibTg3LjA5IDgwLjUxaDIuNWw0IDkuNDRoLTIuNzlsLS42Ny0xLjY5aC0zLjYzbC0uNjcgMS43NGgtMi43MXptMi4yOCA1LjczLTEuMDUtMi42NS0xLjA2IDIuNjV6Ii8+PHBhdGggZD0ibTk0IDgwLjU1aDIuNnY5LjM3aC0yLjZ6Ii8+PHBhdGggZD0ibTk3LjU2IDgwLjU1aDIuNDRsMy4zNyA1di01aDIuNTd2OS4zN2gtMi4yN2wtMy41My01LjE0djUuMTRoLTIuNTh6Ii8+PHBhdGggZD0ibTEwNi4zNyA4OC41MyAxLjQ0LTEuNzNhNC44NiA0Ljg2IDAgMCAwIDMgMS4xM2MuNzEgMCAxLjA4LS4yNSAxLjA4LS42NSAwLS40MS0uMy0uNjEtMS41OS0uOTEtMi0uNDYtMy41My0xLTMuNTMtMi45MyAwLTEuNzQgMS4zOC0zIDMuNjMtM2E1Ljg4IDUuODggMCAwIDEgMy44NSAxLjI1bC0xLjI1IDEuNzhhNC41NiA0LjU2IDAgMCAwIC0yLjYyLS45MmMtLjYzIDAtLjk0LjI1LS45NC42IDAgLjQzLjMyLjYyIDEuNjMuOTEgMi4xNS40NyAzLjQ4IDEuMTcgMy40OCAyLjkyIDAgMS45MS0xLjUxIDMtMy43OCAzYTYuNTYgNi41NiAwIDAgMSAtNC40LTEuNDV6Ii8+PC9nPjxwYXRoIGQ9Im0wIDBoMTgwdjE4MGgtMTgweiIgZmlsbD0ibm9uZSIvPjwvc3ZnPg==

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
PHN2ZyBpZD0iYjZiZGQyYjQtNTJhYi00ODhhLTlhMzAtMWU2ZDFkN2RkMmQ0IiBkYXRhLW5hbWU9IkxheWVyIDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDYxMS44IDE0NCI+PGRlZnM+PHN0eWxlPi5hNzM3NDU5Yy1lOGM3LTRhZmEtODAwOC1mNmNmZDE1Y2NkYTJ7ZmlsbDojZTAwO308L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNTc5LjMsOTIuM2MwLDExLjksNy4yLDE3LjcsMjAuMiwxNy43YTUzLjM5LDUzLjM5LDAsMCwwLDExLjktMS43Vjk0LjVhMjUuMjcsMjUuMjcsMCwwLDEtNy43LDEuMmMtNS40LDAtNy40LTEuNy03LjQtNi43VjY3LjhoMTUuNlY1My42SDU5Ni4zdi0xOGwtMTcsMy43VjUzLjZINTY4VjY3LjhoMTEuMmwuMSwyNC41Wm0tNTMsLjNjMC0zLjcsMy43LTUuNSw5LjMtNS41YTM4LjM1LDM4LjM1LDAsMCwxLDEwLjEsMS4zdjcuMmEyMC44MiwyMC44MiwwLDAsMS0xMC42LDIuNmMtNS41LDAtOC44LTIuMS04LjgtNS42bTUuMiwxNy42YTI2LjY5LDI2LjY5LDAsMCwwLDE1LjQtNC4zdjMuNGgxNi44VjczLjZjMC0xMy42LTkuMS0yMS0yNC40LTIxLTguNSwwLTE2LjksMi0yNiw2LjFsNi4xLDEyLjVjNi41LTIuNywxMi00LjQsMTYuOC00LjQsNywwLDEwLjYsMi43LDEwLjYsOC4zdjIuN2E0OC45Miw0OC45MiwwLDAsMC0xMi42LTEuNmMtMTQuMywwLTIyLjksNi0yMi45LDE2LjcsMCw5LjgsNy44LDE3LjMsMjAuMiwxNy4zbS05Mi40LS45aDE4LjFWODAuNGgzMC4zdjI4LjhoMTguMVYzNS42SDQ4Ny41VjYzLjlINDU3LjJWMzUuNkg0MzkuMVpNMzcwLjIsODEuNGMwLTgsNi4zLTE0LjEsMTQuNi0xNC4xYTE3LjcyLDE3LjcyLDAsMCwxLDExLjgsNC4zVjkxLjFhMTYuNjIsMTYuNjIsMCwwLDEtMTEuOCw0LjVjLTguMi0uMS0xNC42LTYuMi0xNC42LTE0LjJtMjYuNiwyNy45aDE2LjhWMzEuOWwtMTcsMy43VjU2LjVhMjguMTQsMjguMTQsMCwwLDAtMTQuMi0zLjdjLTE2LjIsMC0yOC45LDEyLjUtMjguOSwyOC41YTI4LjI1LDI4LjI1LDAsMCwwLDI3LjksMjguNmguNWEyNS40NiwyNS40NiwwLDAsMCwxNC45LTQuOFpNMzE5LjYsNjYuNWM1LjQsMCw5LjksMy41LDExLjcsOC44SDMwOC4xYTExLjU2LDExLjU2LDAsMCwxLDExLjUtOC44bS0yOC43LDE1YzAsMTYuMiwxMy4yLDI4LjgsMzAuMywyOC44LDkuNCwwLDE2LjItMi41LDIzLjItOC40bC0xMS4zLTEwYy0yLjYsMi43LTYuNSw0LjItMTEuMSw0LjJhMTQuMzcsMTQuMzcsMCwwLDEtMTMuNy04LjhoMzkuNlY4My4xYzAtMTcuNy0xMS45LTMwLjQtMjguMS0zMC40YTI4LjU4LDI4LjU4LDAsMCwwLTI5LDI4LjEsMS40OCwxLjQ4LDAsMCwxLC4xLjdNMjYxLjYsNTEuMWM2LDAsOS40LDMuOCw5LjQsOC4zcy0zLjQsOC4zLTkuNCw4LjNIMjQzLjdWNTEuMVptLTM2LDU4LjFoMTguMVY4Mi40aDEzLjhsMTMuOSwyNi44aDIwLjJMMjc1LjQsNzkuN0EyMi4zMiwyMi4zMiwwLDAsMCwyODkuMyw1OWMwLTEzLjItMTAuNC0yMy41LTI2LTIzLjVIMjI1LjZ2NzMuN1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PHBhdGggY2xhc3M9ImE3Mzc0NTljLWU4YzctNGFmYS04MDA4LWY2Y2ZkMTVjY2RhMiIgZD0iTTEyNy4xLDgzYzEyLjUsMCwzMC42LTIuNiwzMC42LTE3LjVhMTkuNTMsMTkuNTMsMCwwLDAtLjMtMy40TDE1MCwyOS43Yy0xLjctNy4xLTMuMi0xMC40LTE1LjctMTYuNkMxMjQuNiw4LjEsMTAzLjUsMCw5Ny4yLDBjLTUuOSwwLTcuNiw3LjUtMTQuNSw3LjVDNzYsNy41LDcxLjEsMS45LDY0LjgsMS45Yy02LDAtOS45LDQuMS0xMi45LDEyLjUsMCwwLTguNCwyMy43LTkuNSwyNy4yYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljLS4xLDkuMiwzNi4yLDM5LjQsODQuOSwzOS41bTMyLjUtMTEuNGMxLjcsOC4yLDEuNyw5LjEsMS43LDEwLjEsMCwxNC0xNS43LDIxLjgtMzYuNCwyMS44LTQ2LjgsMC04Ny43LTI3LjQtODcuNy00NS41YTE4LjM1LDE4LjM1LDAsMCwxLDEuNS03LjNDMjEuOSw1MS41LjEsNTQuNS4xLDczLjcuMSwxMDUuMiw3NC43LDE0NCwxMzMuNywxNDRjNDUuMywwLDU2LjctMjAuNSw1Ni43LTM2LjcsMC0xMi43LTExLTI3LjEtMzAuOC0zNS43IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC4xKSIvPjxwYXRoIGQ9Ik0xNTkuNiw3MS42YzEuNyw4LjIsMS43LDkuMSwxLjcsMTAuMSwwLDE0LTE1LjcsMjEuOC0zNi40LDIxLjgtNDYuOCwwLTg3LjctMjcuNC04Ny43LTQ1LjVhMTguMzUsMTguMzUsMCwwLDEsMS41LTcuM2wzLjctOS4xYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljMCw5LjIsMzYuMywzOS40LDg0LjksMzkuNCwxMi41LDAsMzAuNi0yLjYsMzAuNi0xNy41YTE5LjUzLDE5LjUzLDAsMCwwLS4zLTMuNFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PC9zdmc+

View File

@@ -0,0 +1 @@
PHN2ZyBpZD0iX2RldmVsb3BtZW50LS1hc3NldHMtLWltZy0tX3N2Zy1zcHJpdGVzLS1yZXdlLWRpZ2l0YWwiIHZpZXdCb3g9IjAgMCAyMTAgMzcuNjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+PHBhdGggY2xhc3M9ImJtc3QwIiBkPSJNMTMuOTcgMjkuMzFsLTMuMDctOC4xMmMtMS4xNC0zLjAyLTEuNzgtMy40Mi0zLjQyLTMuNDJ2MTEuNTRIMFYuMTloMTAuMDFjOC41NyAwIDExLjM0IDMuNDcgMTEuMzQgOC4zMiAwIDUtMi42MyA3LjU3LTYuMDQgOC4xMi45OS4zIDIuMTggMS42MyAyLjkyIDMuMTcuOTQgMS45MyAzLjQxIDcuMzMgNC4zNSA5LjUxaC04LjYxek03LjQ4IDYuMzR2NS45NGgyLjEzYzIuNTIgMCAzLjQxLTEuMjQgMy40MS0zLjE3IDAtMi4wOC0xLjE0LTIuNzctMy40Ny0yLjc3SDcuNDh6TTI1LjcxIDI5LjMxVi4xOWgxNi4zNHY2LjE1aC04Ljg3djQuOWg3LjI0djUuOTNoLTcuMjR2NS45aDkuOTZ2Ni4yNHpNNzMuMzEgMjkuMzFoLTcuOTdsLTEuNDktOC40MmMtLjY0LTMuNTItMS4yOS03LjMzLTEuNDMtOS4xNmgtLjA1Yy0uMDYgMS40My0uNyA1LjM0LTEuMzkgOS4xNmwtMS41NCA4LjQyaC04LjE3TDQ0LjE4LjE5aDcuOTJsMS42MyA3Ljg3YzEuMzkgNi41NCAxLjY0IDkuMzYgMS42OSAxMC40NS4yLTIuMzMuNjktNS45NCAxLjQ4LTEwLjI1TDU4LjM5LjE5aDguMzJsMS44OSA5Ljc2Yy40NCAyLjE4Ljk5IDUgMS4xOSA4LjU2aC4wNWMuMTUtMi42MyAxLjA0LTguMjYgMS41OC0xMS4wOUw3Mi45MS4xOWg3Ljk3bC03LjU3IDI5LjEyek04Mi45NiAyOS4zMVYuMTloMTYuMzl2Ni4xNWgtOC45MXY0LjloNy4yOHY1LjkzaC03LjI4djUuOWgxMHY2LjI0eiI+PC9wYXRoPjxwYXRoIGNsYXNzPSJibXN0MSIgZD0iTTIwNy4yMy4xOUgyMTBWMjkuM2gtMi43N3pNMTkyLjk3IDI2LjkzYy00LjgxIDAtOC43Mi0zLjkxLTguNzItOC43MSAwLTQuOCAzLjkxLTguNzEgOC43Mi04LjcxIDQuOCAwIDguNzEgMy45MSA4LjcxIDguNzEgMCA0LjgtMy45MSA4LjcxLTguNzEgOC43MXptMC0yMC4yYy02LjM0IDAtMTEuNDkgNS4xNS0xMS40OSAxMS40OXM1LjE1IDExLjQ5IDExLjQ5IDExLjQ5YzMuNDYgMCA2LjU5LTEuNTMgOC43MS00LjAxdjMuNjFoMi43N1YxOC4yMmMwLTYuMzQtNS4xNS0xMS40OS0xMS40OC0xMS40OXoiPjwvcGF0aD48cGF0aCBjbGFzcz0iYm1zdDEiIGQ9Ik0xNjYuMDIgNy4xM3YyMi4xOGgyLjc3VjkuOWg1Ljk1djE5LjQxaDIuNzdWOS45aDUuN1Y3LjEzaC01LjdWLjE5aC0yLjc3djYuOTR6TTE1MS43NSA5LjVjLTQuOCAwLTguNzIgMy45MS04LjcyIDguNzEgMCA0LjggMy45MSA4LjcxIDguNzIgOC43MSA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MSAwLTQuOC0zLjkxLTguNzEtOC43Mi04Ljcxem0xMS40OSAxNi42NGMwIDYuMzQtNS4xNSAxMS40OS0xMS40OSAxMS40OS01LjU5IDAtMTAuMjUtNC4wMS0xMS4yOS05LjMxaDIuODhjLjk0IDMuNzYgNC4zNiA2LjU0IDguNDIgNi41NCA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MXYtLjQ0Yy0yLjEzIDIuNDctNS4yNSA0LjAxLTguNzIgNC4wMS02LjM0IDAtMTEuNDktNS4xNS0xMS40OS0xMS40OXM1LjE1LTExLjQ5IDExLjQ5LTExLjQ5IDExLjQ5IDUuMTUgMTEuNDkgMTEuNDl2Ny45MXpNMTM1LjAyIDcuMTNoMi43N3YyMi4xOGgtMi43N3pNMTIwLjU1IDkuNWMtNC44IDAtOC43MSAzLjkxLTguNzEgOC43MSAwIDQuOCAzLjkxIDguNzEgOC43MSA4LjcxIDQuOCAwIDguNzEtMy45MSA4LjcxLTguNzEuMDEtNC44LTMuOTEtOC43MS04LjcxLTguNzF6bTExLjQ5IDguNzJjMCA2LjM0LTUuMTUgMTEuNDktMTEuNDkgMTEuNDlzLTExLjQ5LTUuMTUtMTEuNDktMTEuNDkgNS4xNS0xMS40OSAxMS40OS0xMS40OWMzLjQ3IDAgNi41OCAxLjUzIDguNzEgNC4wMVYuMTloMi43OHYxOC4wM3pNMTM2LjQgMGMuODkgMCAxLjU4LjY5IDEuNTggMS41OCAwIC44OS0uNyAxLjU4LTEuNTggMS41OC0uOSAwLTEuNTktLjY5LTEuNTktMS41OCAwLS44OS43LTEuNTggMS41OS0xLjU4ek0xNjcuNCAwYy44OSAwIDEuNTkuNjkgMS41OSAxLjU4IDAgLjg5LS43IDEuNTgtMS41OSAxLjU4LS44OSAwLTEuNTgtLjY5LTEuNTgtMS41OCAwLS44OS42OS0xLjU4IDEuNTgtMS41OHoiPjwvcGF0aD48L3N2Zz4=

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

1235
public/index.html Normal file

File diff suppressed because it is too large Load Diff

26
src/App.js Normal file
View File

@@ -0,0 +1,26 @@
import React from 'react';
import Header from './components/Header';
import Hero from './components/Hero';
import JobsSection from './components/JobsSection';
import TeamAugmentation from './components/TeamAugmentation';
import CompaniesSection from './components/CompaniesSection';
import SupportSection from './components/SupportSection';
import Newsletter from './components/Newsletter';
import Footer from './components/Footer';
function App() {
return (
<div className="App">
<Header />
<Hero />
<JobsSection />
<TeamAugmentation />
<CompaniesSection />
<SupportSection />
<Newsletter />
<Footer />
</div>
);
}
export default App;

View File

@@ -0,0 +1,143 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const CompaniesSection = () => {
const shouldReduce = useReducedMotion();
const companies = [
{
name: "Sanofi",
logo: "/images/sanofi-1768473724873.png",
url: "https://www.sanofi.com/"
},
{
name: "Adidas",
logo: "/images/adidas-1768473724765.svg",
url: "https://adidas.com/"
},
{
name: "Autodesk",
logo: "/images/autodesk-1768473725052.png",
url: "https://www.autodesk.com/"
},
{
name: "Mercedes",
logo: "/images/mercedes-1768473724897.png",
url: "https://www.mercedes-benz.com/"
},
{
name: "BMW",
logo: "/images/bmw-1768473724776.svg",
url: ""
},
{
name: "GitLab",
logo: "/images/gitlab-1768473724755.png",
url: "https://about.gitlab.com/"
},
{
name: "Red Hat",
logo: "/images/red-hat-1768473724874.svg",
url: "https://www.redhat.com/"
},
{
name: "Roche",
logo: "/images/roche-logo-1768473725046.png",
url: "https://roche.com/"
},
{
name: "IBM",
logo: "/images/ibm-1768473724821.svg",
url: "https://www.ibm.com/"
},
{
name: "Société Générale",
logo: "/images/societe-generale-logo-1768473724865.png",
url: "https://www.societegenerale.fr/"
},
{
name: "Decathlon",
logo: "/images/decathlon-1768473724791.png",
url: "https://www.decathlon.com/"
},
{
name: "JetBrains",
logo: "/images/jetbrains-1768473724769.svg",
url: "https://www.jetbrains.com/"
},
{
name: "TotalEnergies",
logo: "/images/totalenergies-1768473725057.svg",
url: "https://totalenergies.com/"
},
{
name: "REWE",
logo: "/images/rewe-1768473725054.svg",
url: "https://www.rewe-digital.com/"
},
{
name: "Capgemini",
logo: "/images/capgemini-1768473725054.svg",
url: "https://capgemini.com/"
}
];
const CompanyLogo = ({ company, index }) => {
const LogoComponent = shouldReduce ? 'div' : motion.div;
const logoProps = shouldReduce ? {} : fadeUpPreset(index * 0.05, 0.6);
const logoContent = (
<img
src={company.logo}
alt={company.name}
className="h-12 w-auto object-contain grayscale hover:grayscale-0 transition-all duration-300 opacity-60 hover:opacity-100"
/>
);
return (
<LogoComponent {...logoProps} className="flex items-center justify-center p-4">
{company.url ? (
<a href={company.url} target="_blank" rel="noopener noreferrer">
{logoContent}
</a>
) : (
logoContent
)}
</LogoComponent>
);
};
const SectionComponent = shouldReduce ? 'section' : motion.section;
const sectionProps = shouldReduce ? {} : fadeUpPreset(0.1, 0.8);
return (
<SectionComponent {...sectionProps} className="py-16 bg-white">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
Who is using Nest?
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
Nest is proudly powering a large ecosystem of enterprises and products out there. Wanna see your logo here?
<a href="#" className="text-nest-red hover:underline">Find out more</a>.
</p>
</div>
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-8">
{companies.map((company, index) => (
<CompanyLogo key={company.name} company={company} index={index} />
))}
</div>
</div>
</SectionComponent>
);
};
export default CompaniesSection;

55
src/components/Footer.js Normal file
View File

@@ -0,0 +1,55 @@
import React from 'react';
import { Github, X } from 'lucide-react';
const Footer = () => {
return (
<footer className="bg-white py-12 border-t border-gray-200">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center">
{/* Social Links */}
<div className="flex justify-center space-x-6 mb-6">
<a href="https://github.com/nestjs" className="text-gray-400 hover:text-gray-600 transition-colors">
<Github className="w-6 h-6" />
</a>
<a href="https://twitter.com/nestframework" className="text-gray-400 hover:text-gray-600 transition-colors">
<X className="w-6 h-6" />
</a>
</div>
{/* Links */}
<div className="space-y-2 mb-6">
<p className="text-gray-600">
Official NestJS Consulting{' '}
<a href="https://trilon.io" className="text-nest-red hover:underline">
Trilon.io
</a>
</p>
<p className="text-gray-600">
Copyright © 2017-2026{' '}
<a href="#" className="text-nest-red hover:underline">
Kamil Mysliwiec
</a>
</p>
<div className="flex justify-center space-x-4 text-sm">
<a href="#" className="text-nest-red hover:underline">
Terms of Service
</a>
<span className="text-gray-400">|</span>
<a href="#" className="text-nest-red hover:underline">
Privacy Policy
</a>
</div>
<p className="text-gray-500 text-sm">
Designed by{' '}
<a href="#" className="text-nest-red hover:underline">
Jakub Staron
</a>
</p>
</div>
</div>
</div>
</footer>
);
};
export default Footer;

82
src/components/Header.js Normal file
View File

@@ -0,0 +1,82 @@
import React, { useState } from 'react';
import { Menu, X, ChevronDown, Github } from 'lucide-react';
const Header = () => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<header className="fixed top-0 left-0 right-0 z-50 bg-black/90 backdrop-blur-sm">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="flex items-center justify-between h-16">
{/* Logo */}
<div className="flex-shrink-0">
<a href="/" className="flex items-center">
<img
src="/images/logo-small-gradient-1768473724680.svg"
alt="NestJS - A progressive Node.js framework"
className="h-8 w-auto"
/>
</a>
</div>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center space-x-8">
<a href="/" className="text-white hover:text-nest-red transition-colors font-medium">
HOME
</a>
<a href="/jobs" className="text-white hover:text-nest-red transition-colors font-medium">
JOBS
</a>
<a href="/signin" className="text-white hover:text-nest-red transition-colors font-medium">
SIGN IN
</a>
<div className="relative group">
<button className="text-white hover:text-nest-red transition-colors font-medium flex items-center">
RESOURCES
<ChevronDown className="ml-1 w-4 h-4" />
</button>
</div>
<a href="https://github.com/nestjs" className="text-white hover:text-nest-red transition-colors">
<Github className="w-5 h-5" />
</a>
<a href="https://twitter.com/nestframework" className="text-white hover:text-nest-red transition-colors">
<X className="w-5 h-5" />
</a>
</nav>
{/* Mobile menu button */}
<div className="md:hidden">
<button
onClick={() => setIsMenuOpen(!isMenuOpen)}
className="text-white hover:text-nest-red transition-colors"
>
{isMenuOpen ? <X className="w-6 h-6" /> : <Menu className="w-6 h-6" />}
</button>
</div>
</div>
{/* Mobile Navigation */}
{isMenuOpen && (
<div className="md:hidden">
<div className="px-2 pt-2 pb-3 space-y-1 bg-black/95">
<a href="/" className="block px-3 py-2 text-white hover:text-nest-red transition-colors font-medium">
HOME
</a>
<a href="/jobs" className="block px-3 py-2 text-white hover:text-nest-red transition-colors font-medium">
JOBS
</a>
<a href="/signin" className="block px-3 py-2 text-white hover:text-nest-red transition-colors font-medium">
SIGN IN
</a>
<a href="/resources" className="block px-3 py-2 text-white hover:text-nest-red transition-colors font-medium">
RESOURCES
</a>
</div>
</div>
)}
</div>
</header>
);
};
export default Header;

85
src/components/Hero.js Normal file
View File

@@ -0,0 +1,85 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const Hero = () => {
const shouldReduce = useReducedMotion();
if (shouldReduce) {
return (
<section className="relative min-h-screen bg-black flex items-center justify-center overflow-hidden">
<div className="absolute inset-0 bg-hero-gradient z-10"></div>
<div className="absolute right-0 top-0 w-1/2 h-full opacity-30">
<div className="w-full h-full bg-gradient-to-l from-gray-800 to-transparent"></div>
</div>
<div className="relative z-20 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<div className="max-w-4xl mx-auto">
<h1 className="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6">
Official NestJS job board
</h1>
<p className="text-xl md:text-2xl text-gray-300 mb-8 max-w-3xl mx-auto">
Discover companies looking for developers with NestJS experience and find your next role.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="btn-primary text-lg px-8 py-4">
Post a job
</button>
<button className="btn-secondary text-lg px-8 py-4">
Browse open positions
</button>
</div>
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 0.8)}
className="relative min-h-screen bg-black flex items-center justify-center overflow-hidden"
>
<div className="absolute inset-0 bg-hero-gradient z-10"></div>
<div className="absolute right-0 top-0 w-1/2 h-full opacity-30">
<div className="w-full h-full bg-gradient-to-l from-gray-800 to-transparent"></div>
</div>
<div className="relative z-20 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<div className="max-w-4xl mx-auto">
<motion.h1
{...fadeUpPreset(0.2, 0.8)}
className="text-4xl md:text-6xl lg:text-7xl font-bold text-white mb-6"
>
Official NestJS job board
</motion.h1>
<motion.p
{...fadeUpPreset(0.3, 0.8)}
className="text-xl md:text-2xl text-gray-300 mb-8 max-w-3xl mx-auto"
>
Discover companies looking for developers with NestJS experience and find your next role.
</motion.p>
<motion.div
{...fadeUpPreset(0.4, 0.8)}
className="flex flex-col sm:flex-row gap-4 justify-center"
>
<button className="btn-primary text-lg px-8 py-4">
Post a job
</button>
<button className="btn-secondary text-lg px-8 py-4">
Browse open positions
</button>
</motion.div>
</div>
</div>
</motion.section>
);
};
export default Hero;

View File

@@ -0,0 +1,204 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
import { Search, Globe, MapPin, Clock } from 'lucide-react';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const JobsSection = () => {
const shouldReduce = useReducedMotion();
const jobs = [
{
id: 1,
title: "Senior Product Engineer",
company: "Pandektes",
location: "Remote",
country: "🇩🇰 Denmark",
salary: "$120k - $150k",
time: "2 hours ago",
logo: "/images/65dc7731-a4bb-4bbe-bc20-7401691a9ec5-1768473725350.png",
featured: false
},
{
id: 2,
title: "Senior Software Engineer",
company: "Trilon",
location: "Remote",
country: "🌏 Worldwide",
salary: "",
time: "25 days ago",
logo: "/images/612b8b42-9610-43b1-92bd-15373110159f-1768473725226.png",
featured: true
}
];
const expiredJobs = [
{
id: 3,
title: "Full-Stack Developer Angular/NestJS/PHP/MySQL",
company: "Nylon Technology",
location: "Remote",
country: "🇺🇸 United States, Continental...",
salary: "$100k - $130k",
time: "a month ago",
logo: "/images/c54da9a9-c7aa-4d9a-838d-1021b684d957-1768473725205.jpeg"
},
{
id: 4,
title: "Full Stack Typescript Developer (NextJs, NestJs)",
company: "ClickTech",
location: "Remote",
country: "🌏 Worldwide",
salary: "$40k - $50k",
time: "2 months ago",
logo: "/images/3e62a3bc-0bae-4f8b-8e5a-4b14db5ef4ab-1768473725164.jpeg"
},
{
id: 5,
title: "NestJS Testing Specialist (Freelancer/Consultant)",
company: "Kapital",
location: "🌏 Worldwide",
country: "",
salary: "",
time: "2 months ago",
logo: "/images/6e1385c3-7fd6-4444-8fc4-908d4aef24be-1768473725395.png"
}
];
const JobCard = ({ job, index }) => {
const CardComponent = shouldReduce ? 'div' : motion.div;
const cardProps = shouldReduce ? {} : fadeUpPreset(index * 0.1, 0.6);
return (
<CardComponent {...cardProps} className="job-card">
<div className="flex items-start space-x-4">
<img
src={job.logo}
alt={job.company}
className="company-logo"
/>
<div className="flex-1">
<div className="flex items-start justify-between">
<div>
<h3 className="text-lg font-semibold text-gray-900 mb-1">
{job.title}
</h3>
<p className="text-gray-600 mb-2">at {job.company}</p>
{job.featured && (
<span className="featured-badge mb-2 inline-block">
FEATURED
</span>
)}
<div className="flex flex-wrap items-center gap-4 text-sm text-gray-500">
<span className="flex items-center">
<MapPin className="w-4 h-4 mr-1" />
{job.location}
</span>
{job.country && (
<span className="flex items-center">
<Globe className="w-4 h-4 mr-1" />
{job.country}
</span>
)}
{job.salary && (
<span className="flex items-center font-medium text-green-600">
💰 {job.salary}
</span>
)}
</div>
</div>
<div className="text-right text-sm text-gray-500">
<Clock className="w-4 h-4 inline mr-1" />
{job.time}
</div>
</div>
</div>
</div>
</CardComponent>
);
};
const SectionComponent = shouldReduce ? 'section' : motion.section;
const sectionProps = shouldReduce ? {} : fadeUpPreset(0.1, 0.8);
return (
<SectionComponent {...sectionProps} className="py-16 bg-nest-gray">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
Find your next opportunity
</h2>
<p className="text-xl text-gray-600 max-w-3xl mx-auto">
Browse through our list of NestJS jobs, find your perfect match and apply. Use filters for more accurate results!
</p>
</div>
{/* Newsletter Signup */}
<div className="bg-nest-red rounded-lg p-6 mb-8">
<div className="flex flex-col md:flex-row items-center justify-between">
<div className="text-white mb-4 md:mb-0">
<h3 className="text-lg font-semibold mb-1">
Get NestJS jobs right to your inbox
</h3>
<p className="text-pink-100">
Subscribe to our newsletter to get notified.
</p>
</div>
<div className="flex w-full md:w-auto">
<input
type="email"
placeholder="Enter your email"
className="flex-1 md:w-80 px-4 py-2 rounded-l-lg border-0 focus:outline-none focus:ring-2 focus:ring-white"
/>
<button className="bg-white text-nest-red px-6 py-2 rounded-r-lg font-medium hover:bg-gray-100 transition-colors">
Subscribe
</button>
</div>
</div>
</div>
{/* Job Filters */}
<div className="flex flex-wrap gap-4 mb-8">
<div className="flex items-center bg-white rounded-lg px-4 py-2 border">
<Search className="w-5 h-5 text-gray-400 mr-2" />
<span className="text-gray-600">Search</span>
</div>
<div className="flex items-center bg-white rounded-lg px-4 py-2 border">
<Globe className="w-5 h-5 text-gray-400 mr-2" />
<span className="text-gray-600">Location</span>
</div>
<div className="flex items-center bg-white rounded-lg px-4 py-2 border">
<span className="text-gray-600">Remote</span>
</div>
<div className="flex items-center bg-white rounded-lg px-4 py-2 border">
<span className="text-gray-600">Salary</span>
</div>
</div>
{/* Active Jobs */}
<div className="space-y-4 mb-12">
{jobs.map((job, index) => (
<JobCard key={job.id} job={job} index={index} />
))}
</div>
{/* Expired Jobs */}
<div>
<h3 className="text-2xl font-bold text-gray-900 mb-6">Expired listings</h3>
<div className="space-y-4">
{expiredJobs.map((job, index) => (
<JobCard key={job.id} job={job} index={index + jobs.length} />
))}
</div>
</div>
</div>
</SectionComponent>
);
};
export default JobsSection;

View File

@@ -0,0 +1,41 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const Newsletter = () => {
const shouldReduce = useReducedMotion();
const SectionComponent = shouldReduce ? 'section' : motion.section;
const sectionProps = shouldReduce ? {} : fadeUpPreset(0.1, 0.8);
return (
<SectionComponent {...sectionProps} className="py-16 bg-nest-gray">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl md:text-4xl font-bold text-gray-900 mb-4">
Join our Newsletter
</h2>
<p className="text-xl text-gray-600 mb-8 max-w-3xl mx-auto">
Subscribe to stay up to date with the latest Nest updates, features, and videos!
</p>
<div className="flex flex-col sm:flex-row max-w-md mx-auto">
<input
type="email"
placeholder="Enter your email"
className="flex-1 px-4 py-3 rounded-l-lg sm:rounded-r-none rounded-r-lg border border-gray-300 focus:outline-none focus:ring-2 focus:ring-nest-red focus:border-transparent"
/>
<button className="bg-nest-red text-white px-6 py-3 rounded-r-lg sm:rounded-l-none rounded-l-lg font-medium hover:bg-red-600 transition-colors">
Subscribe
</button>
</div>
</div>
</SectionComponent>
);
};
export default Newsletter;

View File

@@ -0,0 +1,34 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const SupportSection = () => {
const shouldReduce = useReducedMotion();
const SectionComponent = shouldReduce ? 'section' : motion.section;
const sectionProps = shouldReduce ? {} : fadeUpPreset(0.1, 0.8);
return (
<SectionComponent {...sectionProps} className="py-16 bg-nest-dark">
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center">
<h2 className="text-3xl md:text-4xl font-bold text-white mb-6">
Does your team need additional support?
</h2>
<p className="text-xl text-gray-300 mb-8 max-w-4xl mx-auto">
Nest core team members can work directly with your team on a daily basis to help take your project to the next-level. Let us partner with you and your team to develop the most ambitious projects.
</p>
<button className="btn-primary text-lg px-8 py-4">
Contact us
</button>
</div>
</SectionComponent>
);
};
export default SupportSection;

View File

@@ -0,0 +1,41 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
const fadeUpPreset = (delay = 0, duration = 1.2) => ({
initial: { opacity: 0, y: 20 },
whileInView: { opacity: 1, y: 0 },
viewport: { once: true, amount: 0.2 },
transition: { delay, duration, ease: "easeOut" }
});
const TeamAugmentation = () => {
const shouldReduce = useReducedMotion();
const SectionComponent = shouldReduce ? 'section' : motion.section;
const sectionProps = shouldReduce ? {} : fadeUpPreset(0.1, 0.8);
return (
<SectionComponent {...sectionProps} className="py-16 bg-nest-red relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-nest-red to-pink-600"></div>
<div className="absolute right-0 top-0 w-1/3 h-full opacity-20">
<div className="w-full h-full bg-gradient-to-l from-black/30 to-transparent"></div>
</div>
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div className="max-w-4xl">
<h2 className="text-3xl md:text-4xl lg:text-5xl font-bold text-white mb-6">
Team augmentation. By your side at every step
</h2>
<p className="text-xl text-pink-100 mb-8 max-w-3xl">
Nest core team members can work directly with your team on a daily basis to help take your project to the next-level. Let us partner with you and your team to develop the most ambitious projects.
</p>
<button className="bg-white text-nest-red px-8 py-4 rounded-full font-semibold hover:bg-gray-100 transition-colors text-lg">
Contact us to learn more
</button>
</div>
</div>
</SectionComponent>
);
};
export default TeamAugmentation;

31
src/index.css Normal file
View File

@@ -0,0 +1,31 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
body {
@apply font-sans text-nest-text;
}
}
@layer components {
.btn-primary {
@apply bg-nest-red hover:bg-red-600 text-white px-6 py-3 rounded-full font-medium transition-colors duration-200;
}
.btn-secondary {
@apply border-2 border-white text-white hover:bg-white hover:text-nest-dark px-6 py-3 rounded-full font-medium transition-all duration-200;
}
.job-card {
@apply bg-white rounded-lg shadow-sm border border-gray-200 p-6 hover:shadow-md transition-shadow duration-200;
}
.company-logo {
@apply w-12 h-12 rounded-lg object-contain bg-gray-50 p-2;
}
.featured-badge {
@apply bg-gradient-to-r from-purple-500 to-pink-500 text-white px-3 py-1 rounded-full text-sm font-medium;
}
}

13
src/index.js Normal file
View File

@@ -0,0 +1,13 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import './index.css';
import App from './App';
const container = document.getElementById('root');
const root = createRoot(container);
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);

24
tailwind.config.js Normal file
View File

@@ -0,0 +1,24 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: [
"./src/**/*.{js,jsx,ts,tsx}",
],
theme: {
extend: {
colors: {
'nest-red': '#e91e63',
'nest-pink': '#e91e63',
'nest-dark': '#1a1a1a',
'nest-gray': '#f5f5f5',
'nest-text': '#333333'
},
fontFamily: {
'sans': ['Inter', 'system-ui', 'sans-serif']
},
backgroundImage: {
'hero-gradient': 'linear-gradient(135deg, rgba(0,0,0,0.8) 0%, rgba(0,0,0,0.4) 100%)'
}
},
},
plugins: [],
}

5
vercel.json Normal file
View File

@@ -0,0 +1,5 @@
{
"installCommand": "npm install",
"buildCommand": "CI=false npm run build",
"outputDirectory": "build"
}