From 04b58427a90788f151b6ed7e45a300951851e6db Mon Sep 17 00:00:00 2001 From: vitaliimulika-dev Date: Mon, 19 Jan 2026 17:58:34 +0200 Subject: [PATCH] Initial commit --- .env.production | 1 + .gitea/workflows/build.yml | 62 ++ package.json | 41 + postcss.config.js | 6 + public/index.html | 1235 +++++++++++++++++++++++++++ src/App.js | 28 + src/components/AccelerateSection.js | 96 +++ src/components/CTASection.js | 61 ++ src/components/CompanyLogos.js | 118 +++ src/components/Footer.js | 43 + src/components/Header.js | 76 ++ src/components/Hero.js | 73 ++ src/components/Newsletter.js | 102 +++ src/components/ServicesSection.js | 131 +++ src/components/TeamAugmentation.js | 67 ++ src/index.css | 27 + src/index.js | 13 + tailwind.config.js | 26 + vercel.json | 5 + 19 files changed, 2211 insertions(+) create mode 100644 .env.production create mode 100644 .gitea/workflows/build.yml create mode 100644 package.json create mode 100644 postcss.config.js create mode 100644 public/index.html create mode 100644 src/App.js create mode 100644 src/components/AccelerateSection.js create mode 100644 src/components/CTASection.js create mode 100644 src/components/CompanyLogos.js create mode 100644 src/components/Footer.js create mode 100644 src/components/Header.js create mode 100644 src/components/Hero.js create mode 100644 src/components/Newsletter.js create mode 100644 src/components/ServicesSection.js create mode 100644 src/components/TeamAugmentation.js create mode 100644 src/index.css create mode 100644 src/index.js create mode 100644 tailwind.config.js create mode 100644 vercel.json diff --git a/.env.production b/.env.production new file mode 100644 index 0000000..02269f0 --- /dev/null +++ b/.env.production @@ -0,0 +1 @@ +DISABLE_ESLINT_PLUGIN=true diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..8687ee0 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -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" diff --git a/package.json b/package.json new file mode 100644 index 0000000..728af62 --- /dev/null +++ b/package.json @@ -0,0 +1,41 @@ +{ + "name": "nestjs-enterprise", + "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" + ] + } +} \ No newline at end of file diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..96bb01e --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} \ No newline at end of file diff --git a/public/index.html b/public/index.html new file mode 100644 index 0000000..5a6c47d --- /dev/null +++ b/public/index.html @@ -0,0 +1,1235 @@ + + + + + + + + + + + + NestJS Enterprise - Official Support + + + +
+ + + + + \ No newline at end of file diff --git a/src/App.js b/src/App.js new file mode 100644 index 0000000..67b78d1 --- /dev/null +++ b/src/App.js @@ -0,0 +1,28 @@ +import React from 'react'; +import Header from './components/Header'; +import Hero from './components/Hero'; +import AccelerateSection from './components/AccelerateSection'; +import TeamAugmentation from './components/TeamAugmentation'; +import CompanyLogos from './components/CompanyLogos'; +import ServicesSection from './components/ServicesSection'; +import CTASection from './components/CTASection'; +import Newsletter from './components/Newsletter'; +import Footer from './components/Footer'; + +function App() { + return ( +
+
+ + + + + + + +
+
+ ); +} + +export default App; \ No newline at end of file diff --git a/src/components/AccelerateSection.js b/src/components/AccelerateSection.js new file mode 100644 index 0000000..3439733 --- /dev/null +++ b/src/components/AccelerateSection.js @@ -0,0 +1,96 @@ +import React from 'react'; +import { motion, useReducedMotion } from 'framer-motion'; +import { Check } 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 AccelerateSection = () => { + const shouldReduce = useReducedMotion(); + + const features = [ + "Providing technical guidance & architectural reviews", + "Mentoring team members", + "Advising best practices", + "Addressing security & performance concerns", + "Performing in-depth code reviews", + "Long-term support (LTS) & upgrade assistance" + ]; + + if (shouldReduce) { + return ( +
+
+
+
+

+ Accelerate your development +

+

+ We work alongside you to meet your deadlines while avoiding costly tech debt. Challenging issue? We've got you covered. +

+

+ Our goal is to help you get to market faster. Nest core team members will help you utilize best practices and choose the right strategy for unique goals. +

+ +
+
+ {features.map((feature, index) => ( +
+ + {feature} +
+ ))} +
+
+
+
+ ); + } + + return ( + +
+
+ +

+ Accelerate your development +

+

+ We work alongside you to meet your deadlines while avoiding costly tech debt. Challenging issue? We've got you covered. +

+

+ Our goal is to help you get to market faster. Nest core team members will help you utilize best practices and choose the right strategy for unique goals. +

+ +
+ + {features.map((feature, index) => ( + + + {feature} + + ))} + +
+
+
+ ); +}; + +export default AccelerateSection; \ No newline at end of file diff --git a/src/components/CTASection.js b/src/components/CTASection.js new file mode 100644 index 0000000..5a548ac --- /dev/null +++ b/src/components/CTASection.js @@ -0,0 +1,61 @@ +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 CTASection = () => { + const shouldReduce = useReducedMotion(); + + if (shouldReduce) { + return ( +
+
+

+ Explore enterprise services today. +

+

+ Let's achieve your most ambitious goals - together. +

+ +
+
+ ); + } + + return ( + +
+ + Explore enterprise services today. + + + Let's achieve your most ambitious goals - together. + + + Contact us + +
+
+ ); +}; + +export default CTASection; \ No newline at end of file diff --git a/src/components/CompanyLogos.js b/src/components/CompanyLogos.js new file mode 100644 index 0000000..731f651 --- /dev/null +++ b/src/components/CompanyLogos.js @@ -0,0 +1,118 @@ +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 CompanyLogos = () => { + const shouldReduce = useReducedMotion(); + + const companies = [ + { name: "Sanofi", logo: "https://enterprise.nestjs.com/sanofi.b18c1526.png", url: "https://www.sanofi.com/" }, + { name: "Adidas", logo: "https://enterprise.nestjs.com/adidas.718f26f2.svg", url: "https://adidas.com/" }, + { name: "Autodesk", logo: "https://enterprise.nestjs.com/autodesk.a7f2b58e.png", url: "https://www.autodesk.com/" }, + { name: "Mercedes", logo: "https://enterprise.nestjs.com/mercedes.ee8047a9.png", url: "https://www.mercedes-benz.com/" }, + { name: "GitLab", logo: "https://enterprise.nestjs.com/gitlab.4f9d2995.png", url: "https://about.gitlab.com/" }, + { name: "Red Hat", logo: "https://enterprise.nestjs.com/red-hat.c5e6e64a.svg", url: "https://www.redhat.com/" }, + { name: "JetBrains", logo: "https://enterprise.nestjs.com/jetbrains.536f2da5.svg", url: "https://www.jetbrains.com/" }, + { name: "Roche", logo: "https://enterprise.nestjs.com/roche-logo.979d9061.png", url: "https://roche.com/" }, + { name: "IBM", logo: "https://enterprise.nestjs.com/ibm.b8c76e06.svg", url: "https://www.ibm.com/" }, + { name: "Société Générale", logo: "https://enterprise.nestjs.com/societe-generale-logo.ec64d013.png", url: "https://www.societegenerale.fr/" }, + { name: "TotalEnergies", logo: "https://enterprise.nestjs.com/totalenergies.5a993082.svg", url: "https://totalenergies.com/" }, + { name: "Decathlon", logo: "https://enterprise.nestjs.com/decathlon.1f3c4744.png", url: "https://www.decathlon.com/" }, + { name: "Capgemini", logo: "https://enterprise.nestjs.com/capgemini.a1d43b77.svg", url: "https://capgemini.com/" }, + { name: "REWE", logo: "https://enterprise.nestjs.com/rewe.1250e1e4.svg", url: "https://www.rewe-digital.com/" }, + { name: "BMW", logo: "https://enterprise.nestjs.com/bmw.0ce4c05c.svg", url: "#" } + ]; + + if (shouldReduce) { + return ( +
+
+

+ Who is using Nest? +

+

+ Nest is proudly powering a large ecosystem of enterprises and products out there. Wanna see your logo here? + Find out more. +

+
+ {companies.map((company, index) => ( +
+ {company.url !== "#" ? ( + + {company.name} + + ) : ( + {company.name} + )} +
+ ))} +
+
+
+ ); + } + + return ( + +
+ + Who is using Nest? + + + Nest is proudly powering a large ecosystem of enterprises and products out there. Wanna see your logo here? + Find out more. + +
+ {companies.map((company, index) => ( + + {company.url !== "#" ? ( + + {company.name} + + ) : ( + {company.name} + )} + + ))} +
+
+
+ ); +}; + +export default CompanyLogos; \ No newline at end of file diff --git a/src/components/Footer.js b/src/components/Footer.js new file mode 100644 index 0000000..b62e35b --- /dev/null +++ b/src/components/Footer.js @@ -0,0 +1,43 @@ +import React from 'react'; +import { Github, X } from 'lucide-react'; + +const Footer = () => { + return ( + + ); +}; + +export default Footer; \ No newline at end of file diff --git a/src/components/Header.js b/src/components/Header.js new file mode 100644 index 0000000..668d727 --- /dev/null +++ b/src/components/Header.js @@ -0,0 +1,76 @@ +import React, { useState } from 'react'; +import { Menu, X, ChevronDown, Github } from 'lucide-react'; + +const Header = () => { + const [isMenuOpen, setIsMenuOpen] = useState(false); + + return ( +
+
+
+ {/* Logo */} +
+ + NestJS - A progressive Node.js framework + +
+ + {/* Desktop Navigation */} + + + {/* Mobile menu button */} + +
+ + {/* Mobile Navigation */} + {isMenuOpen && ( +
+
+ + OUR WEBSITE + + + COURSES + + + NEW + RESOURCES + +
+
+ )} +
+
+ ); +}; + +export default Header; \ No newline at end of file diff --git a/src/components/Hero.js b/src/components/Hero.js new file mode 100644 index 0000000..b097005 --- /dev/null +++ b/src/components/Hero.js @@ -0,0 +1,73 @@ +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 ( +
+
+
+

+ Official support +

+

+ Our Experts become your development partner to eliminate project risk, tackling the most ambitious projects - right by your side. +

+
+ + +
+
+
+ ); + } + + return ( + +
+
+ + Official support + + + Our Experts become your development partner to eliminate project risk, tackling the most ambitious projects - right by your side. + + + + + +
+
+ ); +}; + +export default Hero; \ No newline at end of file diff --git a/src/components/Newsletter.js b/src/components/Newsletter.js new file mode 100644 index 0000000..410f333 --- /dev/null +++ b/src/components/Newsletter.js @@ -0,0 +1,102 @@ +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 [email, setEmail] = useState(''); + const shouldReduce = useReducedMotion(); + + const handleSubmit = (e) => { + e.preventDefault(); + console.log('Newsletter signup:', email); + setEmail(''); + }; + + if (shouldReduce) { + return ( +
+
+
+

+ Join our Newsletter +

+

+ Subscribe to stay up to date with the latest Nest updates, features, and videos! +

+
+ setEmail(e.target.value)} + placeholder="Enter your email" + className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-nest-red focus:border-transparent" + required + /> + +
+
+
+
+ ); + } + + return ( + +
+
+ + Join our Newsletter + + + Subscribe to stay up to date with the latest Nest updates, features, and videos! + + + setEmail(e.target.value)} + placeholder="Enter your email" + className="flex-1 px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-nest-red focus:border-transparent" + required + /> + + +
+
+
+ ); +}; + +export default Newsletter; \ No newline at end of file diff --git a/src/components/ServicesSection.js b/src/components/ServicesSection.js new file mode 100644 index 0000000..6a44680 --- /dev/null +++ b/src/components/ServicesSection.js @@ -0,0 +1,131 @@ +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 ServicesSection = () => { + const shouldReduce = useReducedMotion(); + + const services = [ + { + icon: "https://enterprise.nestjs.com/startup.b4dbf43d.svg", + title: "DEVELOPMENT", + description: "Achieve your goals faster with Nest experts on your team tackling challenging issues right by your side." + }, + { + icon: "https://enterprise.nestjs.com/conversation.2689303c.svg", + title: "TECHNICAL GUIDANCE", + description: "Enable your team to get the most out of the technology. Ensure your solutions are secure and reliable." + }, + { + icon: "https://enterprise.nestjs.com/big-data.88454030.svg", + title: "MIGRATION ASSISTANCE", + description: "We provide a comprehensive migration assistance, ensuring you are using the latest and greatest." + }, + { + icon: "https://enterprise.nestjs.com/puzzle.a43aa4b7.svg", + title: "IN-DEPTH CODE REVIEWS", + description: "Frequent code reviews can eliminate potentially hazardous bugs and issues at an early stage while enforcing best practices." + }, + { + icon: "https://enterprise.nestjs.com/protect.5939735a.svg", + title: "LONG-TERM SUPPORT (LTS)", + description: "Have peace of mind with Nest long-term support (LTS), priority fixes, upgrade assistance, and live troubleshooting." + }, + { + icon: "https://enterprise.nestjs.com/hired.123ab98d.svg", + title: "TEAM TRAININGS", + description: "Level-up your team by having expert-led Nest trainings or workshops. Get everyone up-to-speed quickly." + } + ]; + + if (shouldReduce) { + return ( +
+
+
+

+ How can we help you be successful? +

+

+ Nest Enterprise Consulting includes a broad range of services to empower your team. We help you grow your business even long after our commitment is done. +

+
+
+ {services.map((service, index) => ( +
+
+ {service.title} +
+

+ {service.title} +

+

+ {service.description} +

+
+ ))} +
+
+
+ ); + } + + return ( + +
+
+ + How can we help you be successful? + + + Nest Enterprise Consulting includes a broad range of services to empower your team. We help you grow your business even long after our commitment is done. + +
+
+ {services.map((service, index) => ( + +
+ {service.title} +
+

+ {service.title} +

+

+ {service.description} +

+
+ ))} +
+
+
+ ); +}; + +export default ServicesSection; \ No newline at end of file diff --git a/src/components/TeamAugmentation.js b/src/components/TeamAugmentation.js new file mode 100644 index 0000000..c86f698 --- /dev/null +++ b/src/components/TeamAugmentation.js @@ -0,0 +1,67 @@ +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(); + + if (shouldReduce) { + return ( +
+
+
+
+

+ Team augmentation. By your side at every step +

+

+ 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. +

+ +
+
+
+ ); + } + + return ( + +
+
+
+ + Team augmentation. By your side at every step + + + 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. + + + Contact us to learn more + +
+
+
+ ); +}; + +export default TeamAugmentation; \ No newline at end of file diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..0c6662c --- /dev/null +++ b/src/index.css @@ -0,0 +1,27 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + body { + @apply font-sans antialiased; + } +} + +@layer components { + .btn-primary { + @apply bg-nest-red hover:bg-red-600 text-white font-medium px-8 py-3 rounded-full transition-colors duration-200; + } + + .btn-secondary { + @apply border-2 border-white text-white hover:bg-white hover:text-nest-dark font-medium px-8 py-3 rounded-full transition-all duration-200; + } + + .section-padding { + @apply py-16 md:py-24; + } + + .container-custom { + @apply max-w-7xl mx-auto px-4 sm:px-6 lg:px-8; + } +} \ No newline at end of file diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..0881df3 --- /dev/null +++ b/src/index.js @@ -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( + + + +); \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js new file mode 100644 index 0000000..c936440 --- /dev/null +++ b/tailwind.config.js @@ -0,0 +1,26 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./src/**/*.{js,jsx,ts,tsx}", + "./public/index.html" + ], + theme: { + extend: { + colors: { + 'nest-red': '#e53e3e', + 'nest-pink': '#ed64a6', + 'nest-dark': '#1a202c', + 'nest-gray': '#2d3748', + 'nest-light-gray': '#f7fafc' + }, + fontFamily: { + 'sans': ['Inter', 'system-ui', 'sans-serif'] + }, + backgroundImage: { + 'hero-pattern': "url('https://enterprise.nestjs.com/header-2.50296714.jpg')", + 'support-pattern': "url('https://enterprise.nestjs.com/support.cbdb04e7.png')" + } + } + }, + plugins: [] +} \ No newline at end of file diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..760984a --- /dev/null +++ b/vercel.json @@ -0,0 +1,5 @@ +{ + "installCommand": "npm install", + "buildCommand": "CI=false npm run build", + "outputDirectory": "build" +} \ No newline at end of file