Initial commit
This commit is contained in:
1
.env.production
Normal file
1
.env.production
Normal file
@@ -0,0 +1 @@
|
||||
DISABLE_ESLINT_PLUGIN=true
|
||||
62
.gitea/workflows/build.yml
Normal file
62
.gitea/workflows/build.yml
Normal 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
41
package.json
Normal 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
6
postcss.config.js
Normal 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
@@ -0,0 +1 @@
|
||||
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
|
||||
@@ -0,0 +1 @@
|
||||
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
|
||||
File diff suppressed because one or more lines are too long
1
public/images/adidas-1768471894841.svg
Normal file
1
public/images/adidas-1768471894841.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyB2aWV3Qm94PSIwIDAgMTAwIDY4IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBzdHJva2UtbGluZWpvaW49InJvdW5kIiBzdHJva2UtbWl0ZXJsaW1pdD0iMS40MTQiPjxwYXRoIGZpbGw9IiMzMzMiIGQ9Ik00OS43MzUgNTguMzVhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtMTkuNjgyIDBhNC44MjMgNC44MjMgMCAwIDEgNC44MzgtNC44MzggNC44MjIgNC44MjIgMCAwIDEgNC44MzcgNC44MzggNC44MjIgNC44MjIgMCAwIDEtNC44MzcgNC44MzggNC44MjMgNC44MjMgMCAwIDEtNC44MzgtNC44MzhtLTQ1LjYyNiAwYTQuODIyIDQuODIyIDAgMCAxIDQuODM4LTQuODM4IDQuODIyIDQuODIyIDAgMCAxIDQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM3IDQuODM4IDQuODIyIDQuODIyIDAgMCAxLTQuODM4LTQuODM4bS0xOS42ODIgMGE0LjgyMiA0LjgyMiAwIDAgMSA0LjgzNy00LjgzOCA0LjgyMiA0LjgyMiAwIDAgMSA0LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzOCA0LjgzOCA0LjgyMiA0LjgyMiAwIDAgMS00LjgzNy00LjgzOG0zOS43OTQtOC41NDloLTQuMjA4djE2LjkzMmg0LjIwOFY0OS44MDF6TTEzLjc1MSA2Ni43MzNoNC4yMDhWNDkuODAxaC00LjIwOHYxLjM1OWE4LjY5OCA4LjY5OCAwIDAgMC01LjAwMy0xLjU1N0E4LjczOSA4LjczOSAwIDAgMCAwIDU4LjM1YTguNzE4IDguNzE4IDAgMCAwIDguNzQ4IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem02NS4zMDggMGg0LjIwOFY0OS44MDFoLTQuMjA4djEuMzU5YTguNjk4IDguNjk4IDAgMCAwLTUuMDAzLTEuNTU3IDguNzM4IDguNzM4IDAgMCAwLTguNzQ3IDguNzQ3IDguNzE3IDguNzE3IDAgMCAwIDguNzQ3IDguNzQ3IDguNjk4IDguNjk4IDAgMCAwIDUuMDAzLTEuNTU3djEuMTkzem01Ljc2Ni01LjUwMWMuMTMyIDMuNDEzIDMuMDQ4IDUuODMyIDcuOTE5IDUuODMyIDMuOTc2IDAgNy4yNTYtMS43MjMgNy4yNTYtNS41MzMgMC0yLjY1MS0xLjQ5MS00LjIwOC00LjkzNy00Ljg3MWwtMi42ODQtLjUzYy0xLjcyMy0uMzMxLTIuOTE2LS42NjMtMi45MTYtMS42OSAwLTEuMTI2IDEuMTYtMS42MjMgMi42MTgtMS42MjMgMi4xMjEgMCAyLjk4MiAxLjA2IDMuMDQ4IDIuMzE5aDQuMjQyYy0uMjMyLTMuMzE0LTIuODgzLTUuNTMzLTcuMTU3LTUuNTMzLTQuNDA3IDAtNy4wMjUgMi40MTgtNy4wMjUgNS41NjYgMCAzLjg0NCAzLjExNSA0LjQ3MyA1Ljc5OSA0Ljk3bDIuMjIuMzk4YzEuNTkuMjk4IDIuMjg2Ljc2MiAyLjI4NiAxLjY5IDAgLjgyOC0uNzk1IDEuNjU2LTIuNjg0IDEuNjU2LTIuNzUgMC0zLjY0NS0xLjQyNC0zLjY3OC0yLjY1MWgtNC4zMDd6TTMzLjQzMyA0NC4wMzZ2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzkgOC43MzkgMCAwIDAtOC43NDggOC43NDcgOC43MTggOC43MTggMCAwIDAgOC43NDggOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptMjUuOTQ0IDB2Ny4xMjRhOC42OTggOC42OTggMCAwIDAtNS4wMDMtMS41NTcgOC43MzggOC43MzggMCAwIDAtOC43NDcgOC43NDcgOC43MTcgOC43MTcgMCAwIDAgOC43NDcgOC43NDcgOC42OTggOC42OTggMCAwIDAgNS4wMDMtMS41NTd2MS4xOTNoNC4yMDhWNDQuMDM2aC00LjIwOHptLTQ4LjQ0My01LjAwM2wyLjg1IDUuMDAzaDE5LjY0OWwtNy43ODctMTMuNDUzLTE0LjcxMiA4LjQ1em0zMi45NjkgOS4yMTF2LTQuMjA4aDE1LjQ3NEw0Mi44NzYgMTUuNDc0bC0xNC43NDUgOC40NDkgMTEuNTY0IDIwLjExM3Y0LjIwOGg0LjIwOHptMjEuNzM3LTQuMjA4aDE5LjY4Mkw1OS44NzQgMCA0NS4xNjMgOC40ODIgNjUuNjQgNDQuMDM2eiIgZmlsbC1ydWxlPSJub256ZXJvIi8+PC9zdmc+
|
||||
1
public/images/autodesk-1768471894939.png
Normal file
1
public/images/autodesk-1768471894939.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/bmw-1768471895184.svg
Normal file
1
public/images/bmw-1768471895184.svg
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
public/images/capgemini-1768471894879.svg
Normal file
1
public/images/capgemini-1768471894879.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/decathlon-1768471894937.png
Normal file
1
public/images/decathlon-1768471894937.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/gitlab-1768471894835.png
Normal file
1
public/images/gitlab-1768471894835.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/header-2-CGRpDzPN-1768471895137.jpg
Normal file
1
public/images/header-2-CGRpDzPN-1768471895137.jpg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/ibm-1768471894879.svg
Normal file
1
public/images/ibm-1768471894879.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/image-27-1768471894950.png
Normal file
1
public/images/image-27-1768471894950.png
Normal file
@@ -0,0 +1 @@
|
||||
PCFET0NUWVBFIGh0bWw+CjxodG1sIGxhbmc9ImVuIj4KICA8aGVhZD4KICAgIDxtZXRhIGNoYXJzZXQ9InV0Zi04IiAvPgogICAgPGxpbmsgcmVsPSJpY29uIiBocmVmPSIvZmF2aWNvbi5pY28iIC8+CiAgICA8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEiIC8+CiAgICA8bWV0YSBuYW1lPSJ0aGVtZS1jb2xvciIgY29udGVudD0iIzE1MTkyNCIgLz4KICAgIDxtZXRhCiAgICAgIG5hbWU9ImRlc2NyaXB0aW9uIgogICAgICBjb250ZW50PSJOZXN0SlMgam9icyBpcyB0aGUgYmVzdCBwbGFjZSB0byBoaXJlIG9yIGdldCBoaXJlZCBhcyBOZXN0SlMgZGV2ZWxvcGVyLiBGaW5kIE5lc3RKUyB0YWxlbnQgYW5kIHJlYWNoIHRvIHRob3VzYW5kcyBvZiBkZXZlbG9wZXJzLiIKICAgIC8+CiAgICA8bWV0YSBuYW1lPSJyb2JvdHMiIGNvbnRlbnQ9Im5vb2RwIiAvPgogICAgPGxpbmsgcmVsPSJjYW5vbmljYWwiIGhyZWY9Imh0dHBzOi8vam9icy5uZXN0anMuY29tIiAvPgogICAgPG1ldGEgcHJvcGVydHk9Im9nOnVybCIgY29udGVudD0iaHR0cHM6Ly9qb2JzLm5lc3Rqcy5jb20iIC8+CiAgICA8bWV0YSBwcm9wZXJ0eT0ib2c6aW1hZ2UiIGNvbnRlbnQ9Imh0dHBzOi8vbmVzdGpzLmNvbS9pbWcvbmVzdC1vZy5wbmciPgogICAgPG1ldGEgcHJvcGVydHk9Im9nOnR5cGUiIGNvbnRlbnQ9IndlYnNpdGUiIC8+CiAgICA8bWV0YSBuYW1lPSJ0d2l0dGVyOmNhcmQiIGNvbnRlbnQ9InN1bW1hcnlfbGFyZ2VfaW1hZ2UiIC8+CiAgICA8bWV0YQogICAgICBwcm9wZXJ0eT0ib2c6c2l0ZV9uYW1lIgogICAgICBjb250ZW50PSJKb2JzIHwgTmVzdEpTIC0gQSBwcm9ncmVzc2l2ZSBOb2RlLmpzIGZyYW1ld29yayIKICAgIC8+CiAgICA8bWV0YQogICAgICBwcm9wZXJ0eT0ib2c6dGl0bGUiCiAgICAgIGNvbnRlbnQ9IkpvYnMgfCBOZXN0SlMgLSBBIHByb2dyZXNzaXZlIE5vZGUuanMgZnJhbWV3b3JrIgogICAgLz4KICAgIDxtZXRhCiAgICAgIHByb3BlcnR5PSJvZzpkZXNjcmlwdGlvbiIKICAgICAgY29udGVudD0iTmVzdEpTIGpvYnMgaXMgdGhlIGJlc3QgcGxhY2UgdG8gaGlyZSBvciBnZXQgaGlyZWQgYXMgTmVzdEpTIGRldmVsb3Blci4gRmluZCBOZXN0SlMgdGFsZW50IGFuZCByZWFjaCB0byB0aG91c2FuZHMgb2YgZGV2ZWxvcGVycy4iCiAgICAvPgogICAgPG1ldGEKICAgICAgbmFtZT0idHdpdHRlcjp0aXRsZSIKICAgICAgY29udGVudD0iSm9icyB8IE5lc3RKUyAtIEEgcHJvZ3Jlc3NpdmUgTm9kZS5qcyBmcmFtZXdvcmsiCiAgICAvPgogICAgPG1ldGEKICAgICAgbmFtZT0idHdpdHRlcjpkZXNjcmlwdGlvbiIKICAgICAgY29udGVudD0iTmVzdEpTIGpvYnMgaXMgdGhlIGJlc3QgcGxhY2UgdG8gaGlyZSBvciBnZXQgaGlyZWQgYXMgTmVzdEpTIGRldmVsb3Blci4gRmluZCBOZXN0SlMgdGFsZW50IGFuZCByZWFjaCB0byB0aG91c2FuZHMgb2YgZGV2ZWxvcGVycy4iCiAgICAvPgogICAgPGxpbmsgcmVsPSJwcmVjb25uZWN0IiBocmVmPSJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tIj4KICAgIDxsaW5rIHJlbD0icHJlY29ubmVjdCIgaHJlZj0iaHR0cHM6Ly9mb250cy5nc3RhdGljLmNvbSIgY3Jvc3NvcmlnaW4+CiAgICA8bGluayBocmVmPSJodHRwczovL2ZvbnRzLmdvb2dsZWFwaXMuY29tL2Nzcz9mYW1pbHk9TW9udHNlcnJhdDozMDAsNDAwLDUwMCw2MDAsNzAwJmRpc3BsYXk9c3dhcCIgcmVsPSJzdHlsZXNoZWV0IiAvPgogICAgPGxpbmsgcmVsPSJhcHBsZS10b3VjaC1pY29uIiBocmVmPSIvbG9nbzE5Mi5wbmciIC8+CiAgICA8bGluayByZWw9Im1hbmlmZXN0IiBocmVmPSIvbWFuaWZlc3QuanNvbiIgLz4KICAgIDxsaW5rIHJlbD0ibWFzay1pY29uIiBocmVmPSIvaW1nL3NhZmFyaS1waW5uZWQtdGFiLnN2ZyIgY29sb3I9IiNlZDI5NDUiIC8+CiAgICA8c2NyaXB0IGRlZmVyIHNyYz0iaHR0cHM6Ly91c2UuZm9udGF3ZXNvbWUuY29tL3JlbGVhc2VzL3Y2LjQuMi9qcy9hbGwuanMiPjwvc2NyaXB0PgogICAgPHNjcmlwdD4KICAgICAgd2luZG93LmRhdGFMYXllciA9IHdpbmRvdy5kYXRhTGF5ZXIgfHwgW107CiAgICAgIGZ1bmN0aW9uIGd0YWcoKXtkYXRhTGF5ZXIucHVzaChhcmd1bWVudHMpO30KICAgICAgZ3RhZygnanMnLCBuZXcgRGF0ZSgpKTsKCiAgICAgIGd0YWcoJ2NvbmZpZycsICdHLVpFM1NHU0dWMjMnKTsKICAgIDwvc2NyaXB0PgogICAgPHRpdGxlPkpvYnMgfCBOZXN0SlMgLSBBIHByb2dyZXNzaXZlIE5vZGUuanMgZnJhbWV3b3JrPC90aXRsZT4KICAgIDxzY3JpcHQgdHlwZT0ibW9kdWxlIiBjcm9zc29yaWdpbiBzcmM9Ii9hc3NldHMvaW5kZXgtRGhyT0wxUzYuanMiPjwvc2NyaXB0PgogICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiBjcm9zc29yaWdpbiBocmVmPSIvYXNzZXRzL2luZGV4LURFYVhzblhXLmNzcyI+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPG5vc2NyaXB0PllvdSBuZWVkIHRvIGVuYWJsZSBKYXZhU2NyaXB0IHRvIHJ1biB0aGlzIGFwcC48L25vc2NyaXB0PgogICAgPGRpdiBpZD0icm9vdCI+PC9kaXY+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
|
||||
1
public/images/jetbrains-1768471894878.svg
Normal file
1
public/images/jetbrains-1768471894878.svg
Normal 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==
|
||||
1
public/images/logo-small-gradient-1768471894765.svg
Normal file
1
public/images/logo-small-gradient-1768471894765.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/logo192-1768471895134.png
Normal file
1
public/images/logo192-1768471895134.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/mercedes-1768471895025.png
Normal file
1
public/images/mercedes-1768471895025.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/red-hat-1768471894904.svg
Normal file
1
public/images/red-hat-1768471894904.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyBpZD0iYjZiZGQyYjQtNTJhYi00ODhhLTlhMzAtMWU2ZDFkN2RkMmQ0IiBkYXRhLW5hbWU9IkxheWVyIDEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDYxMS44IDE0NCI+PGRlZnM+PHN0eWxlPi5hNzM3NDU5Yy1lOGM3LTRhZmEtODAwOC1mNmNmZDE1Y2NkYTJ7ZmlsbDojZTAwO308L3N0eWxlPjwvZGVmcz48cGF0aCBkPSJNNTc5LjMsOTIuM2MwLDExLjksNy4yLDE3LjcsMjAuMiwxNy43YTUzLjM5LDUzLjM5LDAsMCwwLDExLjktMS43Vjk0LjVhMjUuMjcsMjUuMjcsMCwwLDEtNy43LDEuMmMtNS40LDAtNy40LTEuNy03LjQtNi43VjY3LjhoMTUuNlY1My42SDU5Ni4zdi0xOGwtMTcsMy43VjUzLjZINTY4VjY3LjhoMTEuMmwuMSwyNC41Wm0tNTMsLjNjMC0zLjcsMy43LTUuNSw5LjMtNS41YTM4LjM1LDM4LjM1LDAsMCwxLDEwLjEsMS4zdjcuMmEyMC44MiwyMC44MiwwLDAsMS0xMC42LDIuNmMtNS41LDAtOC44LTIuMS04LjgtNS42bTUuMiwxNy42YTI2LjY5LDI2LjY5LDAsMCwwLDE1LjQtNC4zdjMuNGgxNi44VjczLjZjMC0xMy42LTkuMS0yMS0yNC40LTIxLTguNSwwLTE2LjksMi0yNiw2LjFsNi4xLDEyLjVjNi41LTIuNywxMi00LjQsMTYuOC00LjQsNywwLDEwLjYsMi43LDEwLjYsOC4zdjIuN2E0OC45Miw0OC45MiwwLDAsMC0xMi42LTEuNmMtMTQuMywwLTIyLjksNi0yMi45LDE2LjcsMCw5LjgsNy44LDE3LjMsMjAuMiwxNy4zbS05Mi40LS45aDE4LjFWODAuNGgzMC4zdjI4LjhoMTguMVYzNS42SDQ4Ny41VjYzLjlINDU3LjJWMzUuNkg0MzkuMVpNMzcwLjIsODEuNGMwLTgsNi4zLTE0LjEsMTQuNi0xNC4xYTE3LjcyLDE3LjcyLDAsMCwxLDExLjgsNC4zVjkxLjFhMTYuNjIsMTYuNjIsMCwwLDEtMTEuOCw0LjVjLTguMi0uMS0xNC42LTYuMi0xNC42LTE0LjJtMjYuNiwyNy45aDE2LjhWMzEuOWwtMTcsMy43VjU2LjVhMjguMTQsMjguMTQsMCwwLDAtMTQuMi0zLjdjLTE2LjIsMC0yOC45LDEyLjUtMjguOSwyOC41YTI4LjI1LDI4LjI1LDAsMCwwLDI3LjksMjguNmguNWEyNS40NiwyNS40NiwwLDAsMCwxNC45LTQuOFpNMzE5LjYsNjYuNWM1LjQsMCw5LjksMy41LDExLjcsOC44SDMwOC4xYTExLjU2LDExLjU2LDAsMCwxLDExLjUtOC44bS0yOC43LDE1YzAsMTYuMiwxMy4yLDI4LjgsMzAuMywyOC44LDkuNCwwLDE2LjItMi41LDIzLjItOC40bC0xMS4zLTEwYy0yLjYsMi43LTYuNSw0LjItMTEuMSw0LjJhMTQuMzcsMTQuMzcsMCwwLDEtMTMuNy04LjhoMzkuNlY4My4xYzAtMTcuNy0xMS45LTMwLjQtMjguMS0zMC40YTI4LjU4LDI4LjU4LDAsMCwwLTI5LDI4LjEsMS40OCwxLjQ4LDAsMCwxLC4xLjdNMjYxLjYsNTEuMWM2LDAsOS40LDMuOCw5LjQsOC4zcy0zLjQsOC4zLTkuNCw4LjNIMjQzLjdWNTEuMVptLTM2LDU4LjFoMTguMVY4Mi40aDEzLjhsMTMuOSwyNi44aDIwLjJMMjc1LjQsNzkuN0EyMi4zMiwyMi4zMiwwLDAsMCwyODkuMyw1OWMwLTEzLjItMTAuNC0yMy41LTI2LTIzLjVIMjI1LjZ2NzMuN1oiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PHBhdGggY2xhc3M9ImE3Mzc0NTljLWU4YzctNGFmYS04MDA4LWY2Y2ZkMTVjY2RhMiIgZD0iTTEyNy4xLDgzYzEyLjUsMCwzMC42LTIuNiwzMC42LTE3LjVhMTkuNTMsMTkuNTMsMCwwLDAtLjMtMy40TDE1MCwyOS43Yy0xLjctNy4xLTMuMi0xMC40LTE1LjctMTYuNkMxMjQuNiw4LjEsMTAzLjUsMCw5Ny4yLDBjLTUuOSwwLTcuNiw3LjUtMTQuNSw3LjVDNzYsNy41LDcxLjEsMS45LDY0LjgsMS45Yy02LDAtOS45LDQuMS0xMi45LDEyLjUsMCwwLTguNCwyMy43LTkuNSwyNy4yYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljLS4xLDkuMiwzNi4yLDM5LjQsODQuOSwzOS41bTMyLjUtMTEuNGMxLjcsOC4yLDEuNyw5LjEsMS43LDEwLjEsMCwxNC0xNS43LDIxLjgtMzYuNCwyMS44LTQ2LjgsMC04Ny43LTI3LjQtODcuNy00NS41YTE4LjM1LDE4LjM1LDAsMCwxLDEuNS03LjNDMjEuOSw1MS41LjEsNTQuNS4xLDczLjcuMSwxMDUuMiw3NC43LDE0NCwxMzMuNywxNDRjNDUuMywwLDU2LjctMjAuNSw1Ni43LTM2LjcsMC0xMi43LTExLTI3LjEtMzAuOC0zNS43IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMC4xKSIvPjxwYXRoIGQ9Ik0xNTkuNiw3MS42YzEuNyw4LjIsMS43LDkuMSwxLjcsMTAuMSwwLDE0LTE1LjcsMjEuOC0zNi40LDIxLjgtNDYuOCwwLTg3LjctMjcuNC04Ny43LTQ1LjVhMTguMzUsMTguMzUsMCwwLDEsMS41LTcuM2wzLjctOS4xYTYuMTUsNi4xNSwwLDAsMC0uMiwxLjljMCw5LjIsMzYuMywzOS40LDg0LjksMzkuNCwxMi41LDAsMzAuNi0yLjYsMzAuNi0xNy41YTE5LjUzLDE5LjUzLDAsMCwwLS4zLTMuNFoiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0wLjEpIi8+PC9zdmc+
|
||||
1
public/images/rewe-1768471894868.svg
Normal file
1
public/images/rewe-1768471894868.svg
Normal file
@@ -0,0 +1 @@
|
||||
PHN2ZyBpZD0iX2RldmVsb3BtZW50LS1hc3NldHMtLWltZy0tX3N2Zy1zcHJpdGVzLS1yZXdlLWRpZ2l0YWwiIHZpZXdCb3g9IjAgMCAyMTAgMzcuNjIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSI+PHBhdGggY2xhc3M9ImJtc3QwIiBkPSJNMTMuOTcgMjkuMzFsLTMuMDctOC4xMmMtMS4xNC0zLjAyLTEuNzgtMy40Mi0zLjQyLTMuNDJ2MTEuNTRIMFYuMTloMTAuMDFjOC41NyAwIDExLjM0IDMuNDcgMTEuMzQgOC4zMiAwIDUtMi42MyA3LjU3LTYuMDQgOC4xMi45OS4zIDIuMTggMS42MyAyLjkyIDMuMTcuOTQgMS45MyAzLjQxIDcuMzMgNC4zNSA5LjUxaC04LjYxek03LjQ4IDYuMzR2NS45NGgyLjEzYzIuNTIgMCAzLjQxLTEuMjQgMy40MS0zLjE3IDAtMi4wOC0xLjE0LTIuNzctMy40Ny0yLjc3SDcuNDh6TTI1LjcxIDI5LjMxVi4xOWgxNi4zNHY2LjE1aC04Ljg3djQuOWg3LjI0djUuOTNoLTcuMjR2NS45aDkuOTZ2Ni4yNHpNNzMuMzEgMjkuMzFoLTcuOTdsLTEuNDktOC40MmMtLjY0LTMuNTItMS4yOS03LjMzLTEuNDMtOS4xNmgtLjA1Yy0uMDYgMS40My0uNyA1LjM0LTEuMzkgOS4xNmwtMS41NCA4LjQyaC04LjE3TDQ0LjE4LjE5aDcuOTJsMS42MyA3Ljg3YzEuMzkgNi41NCAxLjY0IDkuMzYgMS42OSAxMC40NS4yLTIuMzMuNjktNS45NCAxLjQ4LTEwLjI1TDU4LjM5LjE5aDguMzJsMS44OSA5Ljc2Yy40NCAyLjE4Ljk5IDUgMS4xOSA4LjU2aC4wNWMuMTUtMi42MyAxLjA0LTguMjYgMS41OC0xMS4wOUw3Mi45MS4xOWg3Ljk3bC03LjU3IDI5LjEyek04Mi45NiAyOS4zMVYuMTloMTYuMzl2Ni4xNWgtOC45MXY0LjloNy4yOHY1LjkzaC03LjI4djUuOWgxMHY2LjI0eiI+PC9wYXRoPjxwYXRoIGNsYXNzPSJibXN0MSIgZD0iTTIwNy4yMy4xOUgyMTBWMjkuM2gtMi43N3pNMTkyLjk3IDI2LjkzYy00LjgxIDAtOC43Mi0zLjkxLTguNzItOC43MSAwLTQuOCAzLjkxLTguNzEgOC43Mi04LjcxIDQuOCAwIDguNzEgMy45MSA4LjcxIDguNzEgMCA0LjgtMy45MSA4LjcxLTguNzEgOC43MXptMC0yMC4yYy02LjM0IDAtMTEuNDkgNS4xNS0xMS40OSAxMS40OXM1LjE1IDExLjQ5IDExLjQ5IDExLjQ5YzMuNDYgMCA2LjU5LTEuNTMgOC43MS00LjAxdjMuNjFoMi43N1YxOC4yMmMwLTYuMzQtNS4xNS0xMS40OS0xMS40OC0xMS40OXoiPjwvcGF0aD48cGF0aCBjbGFzcz0iYm1zdDEiIGQ9Ik0xNjYuMDIgNy4xM3YyMi4xOGgyLjc3VjkuOWg1Ljk1djE5LjQxaDIuNzdWOS45aDUuN1Y3LjEzaC01LjdWLjE5aC0yLjc3djYuOTR6TTE1MS43NSA5LjVjLTQuOCAwLTguNzIgMy45MS04LjcyIDguNzEgMCA0LjggMy45MSA4LjcxIDguNzIgOC43MSA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MSAwLTQuOC0zLjkxLTguNzEtOC43Mi04Ljcxem0xMS40OSAxNi42NGMwIDYuMzQtNS4xNSAxMS40OS0xMS40OSAxMS40OS01LjU5IDAtMTAuMjUtNC4wMS0xMS4yOS05LjMxaDIuODhjLjk0IDMuNzYgNC4zNiA2LjU0IDguNDIgNi41NCA0LjgxIDAgOC43Mi0zLjkxIDguNzItOC43MXYtLjQ0Yy0yLjEzIDIuNDctNS4yNSA0LjAxLTguNzIgNC4wMS02LjM0IDAtMTEuNDktNS4xNS0xMS40OS0xMS40OXM1LjE1LTExLjQ5IDExLjQ5LTExLjQ5IDExLjQ5IDUuMTUgMTEuNDkgMTEuNDl2Ny45MXpNMTM1LjAyIDcuMTNoMi43N3YyMi4xOGgtMi43N3pNMTIwLjU1IDkuNWMtNC44IDAtOC43MSAzLjkxLTguNzEgOC43MSAwIDQuOCAzLjkxIDguNzEgOC43MSA4LjcxIDQuOCAwIDguNzEtMy45MSA4LjcxLTguNzEuMDEtNC44LTMuOTEtOC43MS04LjcxLTguNzF6bTExLjQ5IDguNzJjMCA2LjM0LTUuMTUgMTEuNDktMTEuNDkgMTEuNDlzLTExLjQ5LTUuMTUtMTEuNDktMTEuNDkgNS4xNS0xMS40OSAxMS40OS0xMS40OWMzLjQ3IDAgNi41OCAxLjUzIDguNzEgNC4wMVYuMTloMi43OHYxOC4wM3pNMTM2LjQgMGMuODkgMCAxLjU4LjY5IDEuNTggMS41OCAwIC44OS0uNyAxLjU4LTEuNTggMS41OC0uOSAwLTEuNTktLjY5LTEuNTktMS41OCAwLS44OS43LTEuNTggMS41OS0xLjU4ek0xNjcuNCAwYy44OSAwIDEuNTkuNjkgMS41OSAxLjU4IDAgLjg5LS43IDEuNTgtMS41OSAxLjU4LS44OSAwLTEuNTgtLjY5LTEuNTgtMS41OCAwLS44OS42OS0xLjU4IDEuNTgtMS41OHoiPjwvcGF0aD48L3N2Zz4=
|
||||
1
public/images/roche-logo-1768471894838.png
Normal file
1
public/images/roche-logo-1768471894838.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/safari-pinned-tab-1768471895146.svg
Normal file
1
public/images/safari-pinned-tab-1768471895146.svg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/sanofi-1768471894979.png
Normal file
1
public/images/sanofi-1768471894979.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/societe-generale-logo-1768471895019.png
Normal file
1
public/images/societe-generale-logo-1768471895019.png
Normal file
File diff suppressed because one or more lines are too long
1
public/images/support-ChYF6me3-1768471895183.jpg
Normal file
1
public/images/support-ChYF6me3-1768471895183.jpg
Normal file
File diff suppressed because one or more lines are too long
1
public/images/totalenergies-1768471894867.svg
Normal file
1
public/images/totalenergies-1768471894867.svg
Normal file
File diff suppressed because one or more lines are too long
1238
public/index.html
Normal file
1238
public/index.html
Normal file
File diff suppressed because it is too large
Load Diff
26
src/App.js
Normal file
26
src/App.js
Normal 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="min-h-screen bg-white">
|
||||
<Header />
|
||||
<Hero />
|
||||
<JobsSection />
|
||||
<TeamAugmentation />
|
||||
<CompaniesSection />
|
||||
<SupportSection />
|
||||
<Newsletter />
|
||||
<Footer />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
157
src/components/CompaniesSection.js
Normal file
157
src/components/CompaniesSection.js
Normal file
@@ -0,0 +1,157 @@
|
||||
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 shouldReduceMotion = useReducedMotion();
|
||||
|
||||
const companies = [
|
||||
{
|
||||
name: 'Sanofi',
|
||||
logo: "/images/sanofi-1768471894979.png",
|
||||
url: 'https://www.sanofi.com/'
|
||||
},
|
||||
{
|
||||
name: 'Adidas',
|
||||
logo: "/images/adidas-1768471894841.svg",
|
||||
url: 'https://adidas.com/'
|
||||
},
|
||||
{
|
||||
name: 'Autodesk',
|
||||
logo: "/images/autodesk-1768471894939.png",
|
||||
url: 'https://www.autodesk.com/'
|
||||
},
|
||||
{
|
||||
name: 'Mercedes',
|
||||
logo: "/images/mercedes-1768471895025.png",
|
||||
url: 'https://www.mercedes-benz.com/'
|
||||
},
|
||||
{
|
||||
name: 'Red Hat',
|
||||
logo: "/images/red-hat-1768471894904.svg",
|
||||
url: 'https://www.redhat.com/'
|
||||
},
|
||||
{
|
||||
name: 'Roche',
|
||||
logo: "/images/roche-logo-1768471894838.png",
|
||||
url: 'https://roche.com/'
|
||||
},
|
||||
{
|
||||
name: 'Société Générale',
|
||||
logo: "/images/societe-generale-logo-1768471895019.png",
|
||||
url: 'https://www.societegenerale.fr/'
|
||||
},
|
||||
{
|
||||
name: 'Decathlon',
|
||||
logo: "/images/decathlon-1768471894937.png",
|
||||
url: 'https://www.decathlon.com/'
|
||||
},
|
||||
{
|
||||
name: 'GitLab',
|
||||
logo: "/images/gitlab-1768471894835.png",
|
||||
url: 'https://about.gitlab.com/'
|
||||
},
|
||||
{
|
||||
name: 'JetBrains',
|
||||
logo: "/images/jetbrains-1768471894878.svg",
|
||||
url: 'https://www.jetbrains.com/'
|
||||
},
|
||||
{
|
||||
name: 'TotalEnergies',
|
||||
logo: "/images/totalenergies-1768471894867.svg",
|
||||
url: 'https://totalenergies.com/'
|
||||
},
|
||||
{
|
||||
name: 'BMW',
|
||||
logo: "/images/bmw-1768471895184.svg"
|
||||
},
|
||||
{
|
||||
name: 'IBM',
|
||||
logo: "/images/ibm-1768471894879.svg",
|
||||
url: 'https://www.ibm.com/'
|
||||
},
|
||||
{
|
||||
name: 'REWE',
|
||||
logo: "/images/rewe-1768471894868.svg",
|
||||
url: 'https://www.rewe-digital.com/'
|
||||
},
|
||||
{
|
||||
name: 'Capgemini',
|
||||
logo: "/images/capgemini-1768471894879.svg",
|
||||
url: 'https://capgemini.com/'
|
||||
}
|
||||
];
|
||||
|
||||
const CompanyLogo = ({ company, index }) => {
|
||||
const logoContent = (
|
||||
<div className="flex items-center justify-center p-6 bg-white rounded-lg shadow-sm hover:shadow-md transition-shadow duration-200">
|
||||
<img
|
||||
src={company.logo}
|
||||
alt={company.name}
|
||||
className="max-h-12 max-w-32 object-contain filter grayscale hover:grayscale-0 transition-all duration-200"
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (company.url) {
|
||||
return (
|
||||
<a href={company.url} target="_blank" rel="noopener noreferrer">
|
||||
{logoContent}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
return logoContent;
|
||||
};
|
||||
|
||||
const AnimatedCompanyLogo = ({ company, index }) => {
|
||||
if (shouldReduceMotion) {
|
||||
return <CompanyLogo company={company} index={index} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(index * 0.05, 0.6)}>
|
||||
<CompanyLogo company={company} index={index} />
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
const sectionContent = (
|
||||
<section 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? Find out more.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-6">
|
||||
{companies.map((company, index) => (
|
||||
<AnimatedCompanyLogo key={company.name} company={company} index={index} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return sectionContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(0.1, 1.0)}>
|
||||
{sectionContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default CompaniesSection;
|
||||
53
src/components/Footer.js
Normal file
53
src/components/Footer.js
Normal file
@@ -0,0 +1,53 @@
|
||||
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">
|
||||
<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>
|
||||
|
||||
<div className="space-y-2 text-gray-600">
|
||||
<p>
|
||||
Official NestJS Consulting{' '}
|
||||
<a href="https://trilon.io" className="text-nest-pink hover:text-nest-red transition-colors">
|
||||
Trilon.io
|
||||
</a>
|
||||
</p>
|
||||
<p>
|
||||
Copyright © 2017-2026{' '}
|
||||
<a href="#" className="text-nest-pink hover:text-nest-red transition-colors">
|
||||
Kamil Mysliwiec
|
||||
</a>
|
||||
</p>
|
||||
<div className="flex justify-center space-x-4 text-sm">
|
||||
<a href="#" className="text-nest-pink hover:text-nest-red transition-colors">
|
||||
Terms of Service
|
||||
</a>
|
||||
<span>|</span>
|
||||
<a href="#" className="text-nest-pink hover:text-nest-red transition-colors">
|
||||
Privacy Policy
|
||||
</a>
|
||||
</div>
|
||||
<p className="text-sm">
|
||||
Designed by{' '}
|
||||
<a href="#" className="text-nest-pink hover:text-nest-red transition-colors">
|
||||
Jakub Staron
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
};
|
||||
|
||||
export default Footer;
|
||||
68
src/components/Header.js
Normal file
68
src/components/Header.js
Normal file
@@ -0,0 +1,68 @@
|
||||
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 text-white">
|
||||
<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 items-center">
|
||||
<a href="/" className="flex items-center">
|
||||
<img
|
||||
src="/images/logo-small-gradient-1768471894765.svg"
|
||||
alt="NestJS - A progressive Node.js framework"
|
||||
className="h-8 w-8"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Desktop Navigation */}
|
||||
<nav className="hidden md:flex items-center space-x-8">
|
||||
<a href="/" className="text-white hover:text-gray-300 transition-colors">HOME</a>
|
||||
<a href="/jobs" className="text-white hover:text-gray-300 transition-colors">JOBS</a>
|
||||
<a href="/signin" className="text-white hover:text-gray-300 transition-colors">SIGN IN</a>
|
||||
<div className="relative group">
|
||||
<button className="flex items-center text-white hover:text-gray-300 transition-colors">
|
||||
RESOURCES
|
||||
<ChevronDown className="ml-1 w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
<a href="https://github.com/nestjs" className="text-white hover:text-gray-300 transition-colors">
|
||||
<Github className="w-5 h-5" />
|
||||
</a>
|
||||
<a href="https://twitter.com/nestframework" className="text-white hover:text-gray-300 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-gray-300"
|
||||
>
|
||||
{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 sm:px-3 bg-black">
|
||||
<a href="/" className="block text-white hover:text-gray-300 px-3 py-2">HOME</a>
|
||||
<a href="/jobs" className="block text-white hover:text-gray-300 px-3 py-2">JOBS</a>
|
||||
<a href="/signin" className="block text-white hover:text-gray-300 px-3 py-2">SIGN IN</a>
|
||||
<a href="/resources" className="block text-white hover:text-gray-300 px-3 py-2">RESOURCES</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
};
|
||||
|
||||
export default Header;
|
||||
85
src/components/Hero.js
Normal file
85
src/components/Hero.js
Normal 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 shouldReduceMotion = useReducedMotion();
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return (
|
||||
<section className="relative min-h-screen bg-black text-white flex items-center overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-black via-black/90 to-transparent z-10"></div>
|
||||
<div className="absolute right-0 top-0 w-1/2 h-full">
|
||||
<div className="w-full h-full bg-gradient-to-l from-gray-800 to-transparent opacity-50"></div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-16">
|
||||
<div className="max-w-2xl">
|
||||
<h1 className="text-4xl md:text-6xl font-bold mb-6 leading-tight">
|
||||
Official NestJS job board
|
||||
</h1>
|
||||
<p className="text-xl md:text-2xl text-gray-300 mb-8 leading-relaxed">
|
||||
Discover companies looking for developers with NestJS experience and find your next role.
|
||||
</p>
|
||||
<div className="flex flex-col sm:flex-row gap-4">
|
||||
<button className="btn-primary">
|
||||
Post a job
|
||||
</button>
|
||||
<button className="btn-secondary">
|
||||
Browse open positions
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.section
|
||||
{...fadeUpPreset(0.1, 1.0)}
|
||||
className="relative min-h-screen bg-black text-white flex items-center overflow-hidden"
|
||||
>
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-black via-black/90 to-transparent z-10"></div>
|
||||
<div className="absolute right-0 top-0 w-1/2 h-full">
|
||||
<div className="w-full h-full bg-gradient-to-l from-gray-800 to-transparent opacity-50"></div>
|
||||
</div>
|
||||
|
||||
<div className="relative z-20 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 pt-16">
|
||||
<div className="max-w-2xl">
|
||||
<motion.h1
|
||||
{...fadeUpPreset(0.2, 1.0)}
|
||||
className="text-4xl md:text-6xl font-bold mb-6 leading-tight"
|
||||
>
|
||||
Official NestJS job board
|
||||
</motion.h1>
|
||||
<motion.p
|
||||
{...fadeUpPreset(0.3, 1.0)}
|
||||
className="text-xl md:text-2xl text-gray-300 mb-8 leading-relaxed"
|
||||
>
|
||||
Discover companies looking for developers with NestJS experience and find your next role.
|
||||
</motion.p>
|
||||
<motion.div
|
||||
{...fadeUpPreset(0.4, 1.0)}
|
||||
className="flex flex-col sm:flex-row gap-4"
|
||||
>
|
||||
<button className="btn-primary">
|
||||
Post a job
|
||||
</button>
|
||||
<button className="btn-secondary">
|
||||
Browse open positions
|
||||
</button>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</motion.section>
|
||||
);
|
||||
};
|
||||
|
||||
export default Hero;
|
||||
255
src/components/JobsSection.js
Normal file
255
src/components/JobsSection.js
Normal file
@@ -0,0 +1,255 @@
|
||||
import React, { useState } 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 shouldReduceMotion = useReducedMotion();
|
||||
const [emailSubscription, setEmailSubscription] = useState('');
|
||||
|
||||
const jobs = [
|
||||
{
|
||||
id: 1,
|
||||
title: 'Senior Product Engineer',
|
||||
company: 'Pandektes',
|
||||
location: 'Remote',
|
||||
country: '🇩🇰 Denmark',
|
||||
salary: '$120k - $150k',
|
||||
timeAgo: '2 hours ago',
|
||||
logo: "/images/65dc7731-a4bb-4bbe-bc20-7401691a9ec5-1768471895970.png",
|
||||
featured: false
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: 'Senior Software Engineer',
|
||||
company: 'Trilon',
|
||||
location: 'Remote',
|
||||
country: '🌏 Worldwide',
|
||||
timeAgo: '25 days ago',
|
||||
logo: "/images/612b8b42-9610-43b1-92bd-15373110159f-1768471895436.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',
|
||||
timeAgo: 'a month ago',
|
||||
logo: "/images/c54da9a9-c7aa-4d9a-838d-1021b684d957-1768471895594.jpeg"
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
title: 'Full Stack Typescript Developer (NextJs, NestJs)',
|
||||
company: 'ClickTech',
|
||||
location: 'Remote',
|
||||
country: '🌏 Worldwide',
|
||||
salary: '$40k - $50k',
|
||||
timeAgo: '2 months ago',
|
||||
logo: "/images/3e62a3bc-0bae-4f8b-8e5a-4b14db5ef4ab-1768471895612.jpeg"
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
title: 'NestJS Testing Specialist (Freelancer/Consultant)',
|
||||
company: 'Kapital',
|
||||
location: '🌏 Worldwide',
|
||||
timeAgo: '2 months ago',
|
||||
logo: "/images/6e1385c3-7fd6-4444-8fc4-908d4aef24be-1768471895728.png"
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
title: 'Full-Stack Engineer (Mid-Senior) [NestJS, NextJS]',
|
||||
company: 'OASYS NOW',
|
||||
location: '🇳🇱 Netherlands, Delft',
|
||||
salary: '$60k - $80k',
|
||||
timeAgo: '2 months ago',
|
||||
logo: "/images/696a0fcf-7bdb-44e2-bb03-dbdb0fb2e18b-1768471895569.jpeg"
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
title: 'Senior Backend Engineer',
|
||||
company: 'Pandektes',
|
||||
location: 'Remote',
|
||||
country: '🇩🇰 Denmark, Copenhagen',
|
||||
salary: '$110k - $140k',
|
||||
timeAgo: '2 months ago',
|
||||
logo: "/images/65dc7731-a4bb-4bbe-bc20-7401691a9ec5-1768471895970.png"
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
title: 'Backend NestJS Developer',
|
||||
company: 'ClickTech',
|
||||
location: 'Remote',
|
||||
country: '🌏 Worldwide',
|
||||
salary: '$40k - $60k',
|
||||
timeAgo: '6 months ago',
|
||||
logo: "/images/3e62a3bc-0bae-4f8b-8e5a-4b14db5ef4ab-1768471895612.jpeg"
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: 'Senior Software Engineer',
|
||||
company: 'Pippen AI',
|
||||
location: 'Remote',
|
||||
country: '🇨🇦 Canada, Toronto',
|
||||
salary: '$70k - $100k',
|
||||
timeAgo: '6 months ago',
|
||||
logo: "/images/69388f1e-2dff-444b-9fc4-9f035bbf654f-1768471895570.jpeg"
|
||||
}
|
||||
];
|
||||
|
||||
const JobCard = ({ job, index }) => {
|
||||
const cardContent = (
|
||||
<div className={`job-card ${job.featured ? 'featured-job' : ''}`}>
|
||||
<div className="flex items-start justify-between mb-4">
|
||||
<div className="flex items-center space-x-4">
|
||||
<img
|
||||
src={job.logo}
|
||||
alt={job.company}
|
||||
className="company-logo"
|
||||
/>
|
||||
<div>
|
||||
<h3 className="font-semibold text-lg text-gray-900">{job.title}</h3>
|
||||
<p className="text-gray-600">at {job.company}</p>
|
||||
{job.featured && (
|
||||
<span className="inline-block bg-nest-pink text-white text-xs px-2 py-1 rounded-full mt-1">
|
||||
✨ FEATURED
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<span className="text-sm text-gray-500">{job.timeAgo}</span>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-wrap items-center gap-4 text-sm text-gray-600">
|
||||
<div className="flex items-center space-x-1">
|
||||
<MapPin className="w-4 h-4" />
|
||||
<span>{job.location}</span>
|
||||
</div>
|
||||
{job.country && (
|
||||
<div className="flex items-center space-x-1">
|
||||
<Globe className="w-4 h-4" />
|
||||
<span>{job.country}</span>
|
||||
</div>
|
||||
)}
|
||||
{job.salary && (
|
||||
<div className="flex items-center space-x-1">
|
||||
<span className="text-green-600 font-medium">💰 {job.salary}</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return cardContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(index * 0.1, 0.8)}>
|
||||
{cardContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
const sectionContent = (
|
||||
<section 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 mb-8">
|
||||
Browse through our list of NestJS jobs, find your perfect match and apply. Use filters for more accurate results!
|
||||
</p>
|
||||
|
||||
<div className="bg-nest-pink text-white p-6 rounded-lg mb-8">
|
||||
<h3 className="text-lg font-semibold mb-4">Get NestJS jobs right to your inbox</h3>
|
||||
<p className="mb-4">Subscribe to our newsletter to get notified.</p>
|
||||
<div className="flex flex-col sm:flex-row gap-2 max-w-md mx-auto">
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
value={emailSubscription}
|
||||
onChange={(e) => setEmailSubscription(e.target.value)}
|
||||
className="flex-1 px-4 py-2 rounded-lg text-black"
|
||||
/>
|
||||
<button className="bg-white text-nest-pink px-6 py-2 rounded-lg font-medium hover:bg-gray-100 transition-colors">
|
||||
Subscribe
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search and Filters */}
|
||||
<div className="bg-white rounded-lg shadow-sm p-6 mb-8">
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
||||
<div className="relative">
|
||||
<Search className="absolute left-3 top-3 w-5 h-5 text-gray-400" />
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search..."
|
||||
className="w-full pl-10 pr-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-nest-pink focus:border-transparent"
|
||||
/>
|
||||
</div>
|
||||
<select className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-nest-pink focus:border-transparent">
|
||||
<option>Location</option>
|
||||
<option>Remote</option>
|
||||
<option>On-site</option>
|
||||
</select>
|
||||
<select className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-nest-pink focus:border-transparent">
|
||||
<option>Seniority</option>
|
||||
<option>Junior</option>
|
||||
<option>Mid</option>
|
||||
<option>Senior</option>
|
||||
</select>
|
||||
<select className="px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-nest-pink focus:border-transparent">
|
||||
<option>Job type</option>
|
||||
<option>Full-time</option>
|
||||
<option>Part-time</option>
|
||||
<option>Contract</option>
|
||||
</select>
|
||||
</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} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return sectionContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(0.1, 1.0)}>
|
||||
{sectionContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default JobsSection;
|
||||
67
src/components/Newsletter.js
Normal file
67
src/components/Newsletter.js
Normal file
@@ -0,0 +1,67 @@
|
||||
import React, { useState } from 'react';
|
||||
import { motion, useReducedMotion } from 'framer-motion';
|
||||
import { Send } 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 Newsletter = () => {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
const [email, setEmail] = useState('');
|
||||
|
||||
const handleSubmit = (e) => {
|
||||
e.preventDefault();
|
||||
// Handle newsletter subscription
|
||||
console.log('Newsletter subscription:', email);
|
||||
setEmail('');
|
||||
};
|
||||
|
||||
const sectionContent = (
|
||||
<section 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">
|
||||
Subscribe to stay up to date with the latest Nest updates, features, and videos!
|
||||
</p>
|
||||
|
||||
<form onSubmit={handleSubmit} className="max-w-md mx-auto">
|
||||
<div className="flex flex-col sm:flex-row gap-2">
|
||||
<input
|
||||
type="email"
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
required
|
||||
className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:ring-2 focus:ring-nest-pink focus:border-transparent"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-primary flex items-center justify-center space-x-2"
|
||||
>
|
||||
<Send className="w-4 h-4" />
|
||||
<span>Subscribe</span>
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return sectionContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(0.1, 1.0)}>
|
||||
{sectionContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Newsletter;
|
||||
41
src/components/SupportSection.js
Normal file
41
src/components/SupportSection.js
Normal 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 SupportSection = () => {
|
||||
const shouldReduceMotion = useReducedMotion();
|
||||
|
||||
const sectionContent = (
|
||||
<section className="py-16 bg-black text-white">
|
||||
<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 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">
|
||||
Contact us
|
||||
</button>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return sectionContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(0.1, 1.0)}>
|
||||
{sectionContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SupportSection;
|
||||
49
src/components/TeamAugmentation.js
Normal file
49
src/components/TeamAugmentation.js
Normal file
@@ -0,0 +1,49 @@
|
||||
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 shouldReduceMotion = useReducedMotion();
|
||||
|
||||
const sectionContent = (
|
||||
<section className="py-16 bg-nest-pink text-white relative overflow-hidden">
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-nest-pink to-nest-red"></div>
|
||||
<div className="relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-12 items-center">
|
||||
<div>
|
||||
<h2 className="text-3xl md:text-4xl font-bold mb-6">
|
||||
Team augmentation. By your side at every step
|
||||
</h2>
|
||||
<p className="text-xl mb-8 text-pink-100">
|
||||
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-pink px-8 py-3 rounded-full font-semibold hover:bg-gray-100 transition-colors">
|
||||
Contact us to learn more
|
||||
</button>
|
||||
</div>
|
||||
<div className="relative">
|
||||
<div className="w-full h-64 bg-gradient-to-br from-pink-400 to-red-500 rounded-lg opacity-50"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
if (shouldReduceMotion) {
|
||||
return sectionContent;
|
||||
}
|
||||
|
||||
return (
|
||||
<motion.div {...fadeUpPreset(0.1, 1.0)}>
|
||||
{sectionContent}
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TeamAugmentation;
|
||||
31
src/index.css
Normal file
31
src/index.css
Normal file
@@ -0,0 +1,31 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
body {
|
||||
@apply font-sans antialiased;
|
||||
}
|
||||
}
|
||||
|
||||
@layer components {
|
||||
.btn-primary {
|
||||
@apply bg-nest-pink hover:bg-nest-red text-white font-medium px-6 py-3 rounded-full transition-colors duration-200;
|
||||
}
|
||||
|
||||
.btn-secondary {
|
||||
@apply border border-white text-white hover:bg-white hover:text-black font-medium px-6 py-3 rounded-full 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;
|
||||
}
|
||||
|
||||
.featured-job {
|
||||
@apply border-l-4 border-nest-pink;
|
||||
}
|
||||
|
||||
.company-logo {
|
||||
@apply w-12 h-12 rounded-lg object-contain bg-gray-50 p-2;
|
||||
}
|
||||
}
|
||||
13
src/index.js
Normal file
13
src/index.js
Normal 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>
|
||||
);
|
||||
20
tailwind.config.js
Normal file
20
tailwind.config.js
Normal file
@@ -0,0 +1,20 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
"./src/**/*.{js,jsx,ts,tsx}",
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
'nest-red': '#e53e3e',
|
||||
'nest-pink': '#e91e63',
|
||||
'nest-dark': '#1a1a1a',
|
||||
'nest-gray': '#f5f5f5'
|
||||
},
|
||||
fontFamily: {
|
||||
'sans': ['Inter', 'system-ui', 'sans-serif']
|
||||
}
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
5
vercel.json
Normal file
5
vercel.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"installCommand": "npm install",
|
||||
"buildCommand": "CI=false npm run build",
|
||||
"outputDirectory": "build"
|
||||
}
|
||||
Reference in New Issue
Block a user