Initial commit

This commit is contained in:
2026-01-20 13:39:17 +02:00
commit 7239b568de
114 changed files with 2454 additions and 0 deletions

30
src/App.js Normal file
View File

@@ -0,0 +1,30 @@
import React from 'react';
import Header from './components/Header';
import Hero from './components/Hero';
import Features from './components/Features';
import EverythingYouNeed from './components/EverythingYouNeed';
import DeploySection from './components/DeploySection';
import CoursesSection from './components/CoursesSection';
import EnterpriseSection from './components/EnterpriseSection';
import LivePreview from './components/LivePreview';
import SupportSection from './components/SupportSection';
import Footer from './components/Footer';
function App() {
return (
<div className="App">
<Header />
<Hero />
<Features />
<EverythingYouNeed />
<DeploySection />
<CoursesSection />
<EnterpriseSection />
<LivePreview />
<SupportSection />
<Footer />
</div>
);
}
export default App;

View File

@@ -0,0 +1,59 @@
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" }
});
function CoursesSection() {
const shouldReduce = useReducedMotion();
if (shouldReduce) {
return (
<section className="section-padding bg-nest-light-gray">
<div className="container-custom">
<div className="bg-white p-12 rounded-lg shadow-sm">
<h3 className="text-3xl font-bold mb-6">
Official NestJS Courses
</h3>
<p className="text-nest-gray mb-8 leading-relaxed max-w-2xl">
Learn from the creators of NestJS. Our comprehensive courses will teach you everything you need to know to build production-ready applications.
</p>
<button className="btn-primary">
Get started
</button>
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-nest-light-gray"
>
<div className="container-custom">
<motion.div
{...fadeUpPreset(0.2, 0.8)}
className="bg-white p-12 rounded-lg shadow-sm"
>
<h3 className="text-3xl font-bold mb-6">
Official NestJS Courses
</h3>
<p className="text-nest-gray mb-8 leading-relaxed max-w-2xl">
Learn from the creators of NestJS. Our comprehensive courses will teach you everything you need to know to build production-ready applications.
</p>
<button className="btn-primary">
Get started
</button>
</motion.div>
</div>
</motion.section>
);
}
export default CoursesSection;

View File

@@ -0,0 +1,94 @@
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" }
});
function DeploySection() {
const shouldReduce = useReducedMotion();
if (shouldReduce) {
return (
<section className="section-padding">
<div className="container-custom">
<div className="grid md:grid-cols-2 gap-8">
{/* Deploy Card */}
<div className="bg-nest-dark text-white p-12 rounded-lg">
<h3 className="text-3xl font-bold mb-6">
Deploy, now!
</h3>
<p className="text-gray-300 mb-8 leading-relaxed">
Deploy your Nest application to the cloud with a single command using our official deployment tools.
</p>
<button className="btn-primary">
Get started
</button>
</div>
{/* Explore Card */}
<div className="bg-nest-red text-white p-12 rounded-lg">
<h3 className="text-3xl font-bold mb-6">
Explore your graph
</h3>
<p className="text-red-100 mb-8 leading-relaxed">
Visualize your application's dependency graph and understand the relationships between modules.
</p>
<button className="bg-white text-nest-red px-6 py-3 rounded-lg font-medium hover:bg-gray-100 transition-colors">
Explore
</button>
</div>
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding"
>
<div className="container-custom">
<div className="grid md:grid-cols-2 gap-8">
{/* Deploy Card */}
<motion.div
{...fadeUpPreset(0.2, 0.8)}
className="bg-nest-dark text-white p-12 rounded-lg"
>
<h3 className="text-3xl font-bold mb-6">
Deploy, now!
</h3>
<p className="text-gray-300 mb-8 leading-relaxed">
Deploy your Nest application to the cloud with a single command using our official deployment tools.
</p>
<button className="btn-primary">
Get started
</button>
</motion.div>
{/* Explore Card */}
<motion.div
{...fadeUpPreset(0.4, 0.8)}
className="bg-nest-red text-white p-12 rounded-lg"
>
<h3 className="text-3xl font-bold mb-6">
Explore your graph
</h3>
<p className="text-red-100 mb-8 leading-relaxed">
Visualize your application's dependency graph and understand the relationships between modules.
</p>
<button className="bg-white text-nest-red px-6 py-3 rounded-lg font-medium hover:bg-gray-100 transition-colors">
Explore
</button>
</motion.div>
</div>
</div>
</motion.section>
);
}
export default DeploySection;

View File

@@ -0,0 +1,80 @@
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" }
});
function EnterpriseSection() {
const shouldReduce = useReducedMotion();
if (shouldReduce) {
return (
<section className="section-padding bg-nest-red text-white">
<div className="container-custom">
<div className="flex flex-col lg:flex-row items-center gap-12">
<div className="lg:w-1/3">
<img
src="https://nestjs.com/img/cat-enterprise.png"
alt="NestJS Enterprise Cat"
className="w-full max-w-sm mx-auto"
/>
</div>
<div className="lg:w-2/3">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
The open source platform designed for the future. Build enterprise.
</h2>
<p className="text-xl mb-8 leading-relaxed text-red-100">
A complete development kit for building scalable server-side applications. Everything you need to take your Node.js app from prototype to enterprise.
</p>
<button className="bg-white text-nest-red px-8 py-4 rounded-lg font-medium text-lg hover:bg-gray-100 transition-colors">
Contact us
</button>
</div>
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-nest-red text-white"
>
<div className="container-custom">
<div className="flex flex-col lg:flex-row items-center gap-12">
<motion.div
{...fadeUpPreset(0.2, 0.8)}
className="lg:w-1/3"
>
<img
src="https://nestjs.com/img/cat-enterprise.png"
alt="NestJS Enterprise Cat"
className="w-full max-w-sm mx-auto"
/>
</motion.div>
<motion.div
{...fadeUpPreset(0.4, 0.8)}
className="lg:w-2/3"
>
<h2 className="text-4xl md:text-5xl font-bold mb-6">
The open source platform designed for the future. Build enterprise.
</h2>
<p className="text-xl mb-8 leading-relaxed text-red-100">
A complete development kit for building scalable server-side applications. Everything you need to take your Node.js app from prototype to enterprise.
</p>
<button className="bg-white text-nest-red px-8 py-4 rounded-lg font-medium text-lg hover:bg-gray-100 transition-colors">
Contact us
</button>
</motion.div>
</div>
</div>
</motion.section>
);
}
export default EnterpriseSection;

View File

@@ -0,0 +1,135 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
import { Package, Zap, Globe, Settings, File, Eye, Users, TrendingUp } 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" }
});
function EverythingYouNeed() {
const shouldReduce = useReducedMotion();
const features = [
{
icon: Package,
title: "POWERFUL CLI",
description: "Nest CLI is a command-line interface tool that helps you to initialize, develop, and maintain your Nest applications."
},
{
icon: Zap,
title: "DEPENDENCY INJECTION",
description: "Built-in inversion of control (IoC) container with a powerful dependency injection system."
},
{
icon: Globe,
title: "MICROSERVICES READY",
description: "Build microservices with different transport layers like TCP, Redis, NATS, RabbitMQ, and more."
},
{
icon: Settings,
title: "TESTING UTILITIES",
description: "Comes with dedicated testing utilities that make it easy to test your applications."
},
{
icon: File,
title: "BUILT-IN DOCUMENTATION",
description: "Automatically generate OpenAPI documentation for your REST APIs using decorators."
},
{
icon: Eye,
title: "GRAPHQL SUPPORT",
description: "First-class support for GraphQL with code-first and schema-first approaches."
},
{
icon: Users,
title: "WEBSOCKETS",
description: "Real-time applications with WebSockets support and Socket.io integration."
},
{
icon: TrendingUp,
title: "PERFORMANCE",
description: "High performance thanks to Fastify integration and other performance optimizations."
}
];
if (shouldReduce) {
return (
<section className="section-padding bg-white">
<div className="container-custom">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Everything you need...
</h2>
<p className="text-xl text-nest-gray max-w-3xl mx-auto">
Built with modern technologies and best practices for enterprise applications.
</p>
</div>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
{features.map((feature, index) => {
const Icon = feature.icon;
return (
<div key={index} className="feature-card text-center">
<Icon className="w-12 h-12 mx-auto mb-4 text-nest-red" />
<h3 className="font-bold text-sm mb-3 text-nest-dark">
{feature.title}
</h3>
<p className="text-sm text-nest-gray leading-relaxed">
{feature.description}
</p>
</div>
);
})}
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-white"
>
<div className="container-custom">
<motion.div
{...fadeUpPreset(0.2, 0.8)}
className="text-center mb-16"
>
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Everything you need...
</h2>
<p className="text-xl text-nest-gray max-w-3xl mx-auto">
Built with modern technologies and best practices for enterprise applications.
</p>
</motion.div>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
{features.map((feature, index) => {
const Icon = feature.icon;
return (
<motion.div
key={index}
{...fadeUpPreset(0.3 + (index * 0.05), 0.6)}
className="feature-card text-center"
>
<Icon className="w-12 h-12 mx-auto mb-4 text-nest-red" />
<h3 className="font-bold text-sm mb-3 text-nest-dark">
{feature.title}
</h3>
<p className="text-sm text-nest-gray leading-relaxed">
{feature.description}
</p>
</motion.div>
);
})}
</div>
</div>
</motion.section>
);
}
export default EverythingYouNeed;

100
src/components/Features.js Normal file
View File

@@ -0,0 +1,100 @@
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" }
});
function Features() {
const shouldReduce = useReducedMotion();
const features = [
{
icon: (
<svg className="w-16 h-16 mx-auto mb-6" viewBox="0 0 100 100" fill="none">
<path d="M20 20h60v60H20z" stroke="#333" strokeWidth="2" fill="none"/>
<path d="M30 30h40v40H30z" stroke="#333" strokeWidth="2" fill="none"/>
<path d="M40 40h20v20H40z" stroke="#333" strokeWidth="2" fill="none"/>
</svg>
),
title: "EXTENSIBLE",
description: "Provides unparalleled flexibility through its meticulously crafted modular architecture."
},
{
icon: (
<svg className="w-16 h-16 mx-auto mb-6" viewBox="0 0 100 100" fill="none">
<path d="M50 10L80 30v40L50 90L20 70V30z" stroke="#e0234e" strokeWidth="2" fill="none"/>
<circle cx="50" cy="50" r="8" fill="#e0234e"/>
<path d="M35 35l30 30M65 35L35 65" stroke="#e0234e" strokeWidth="2"/>
</svg>
),
title: "VERSATILE",
description: "Serves as a robust, elegant, and well-structured foundation for all kinds of server-side applications."
},
{
icon: (
<svg className="w-16 h-16 mx-auto mb-6" viewBox="0 0 100 100" fill="none">
<path d="M50 10L70 30L50 50L30 30z" fill="#333"/>
<path d="M30 50L50 70L70 50L50 30z" fill="#666"/>
<path d="M50 70L70 90L50 110L30 90z" fill="#333"/>
</svg>
),
title: "PROGRESSIVE",
description: "Introduces design patterns and well-established solutions to the Node.js landscape."
}
];
if (shouldReduce) {
return (
<section className="section-padding bg-nest-light-gray">
<div className="container-custom">
<div className="grid md:grid-cols-3 gap-12">
{features.map((feature, index) => (
<div key={index} className="text-center">
{feature.icon}
<h3 className="text-nest-red font-bold text-lg mb-4">
{feature.title}
</h3>
<p className="text-nest-gray leading-relaxed">
{feature.description}
</p>
</div>
))}
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-nest-light-gray"
>
<div className="container-custom">
<div className="grid md:grid-cols-3 gap-12">
{features.map((feature, index) => (
<motion.div
key={index}
{...fadeUpPreset(index * 0.1, 0.8)}
className="text-center"
>
{feature.icon}
<h3 className="text-nest-red font-bold text-lg mb-4">
{feature.title}
</h3>
<p className="text-nest-gray leading-relaxed">
{feature.description}
</p>
</motion.div>
))}
</div>
</div>
</motion.section>
);
}
export default Features;

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

@@ -0,0 +1,61 @@
import React from 'react';
import { Github, X } from 'lucide-react';
function Footer() {
return (
<footer className="bg-nest-light-gray py-12">
<div className="container-custom">
<div className="text-center">
{/* Social Links */}
<div className="flex justify-center space-x-6 mb-8">
<a href="#" className="text-nest-gray hover:text-nest-red transition-colors">
<Github className="h-6 w-6" />
</a>
<a href="#" className="text-nest-gray hover:text-nest-red transition-colors">
<X className="h-6 w-6" />
</a>
<a href="#" className="text-nest-gray hover:text-nest-red transition-colors">
<svg className="h-6 w-6" fill="currentColor" viewBox="0 0 24 24">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
</div>
{/* Footer Text */}
<div className="space-y-2 text-sm text-nest-gray">
<p>Released under the MIT License</p>
<p>
Official NestJS Consulting{' '}
<a href="#" className="text-nest-red hover:underline">
Trilon.io
</a>
</p>
<p>
Copyright © 2017- 2024{' '}
<a href="#" className="text-nest-red hover:underline">
Kamil Mysliwiec
</a>
</p>
<p>
Designed by{' '}
<a href="#" className="text-nest-red hover:underline">
Jakub Staron
</a>
, hosted by{' '}
<a href="#" className="text-nest-red hover:underline">
Netlify
</a>
</p>
<p>
<a href="#" className="text-nest-red hover:underline">
中文说明
</a>
</p>
</div>
</div>
</div>
</footer>
);
}
export default Footer;

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

@@ -0,0 +1,88 @@
import React, { useState } from 'react';
import { Menu, X, ChevronDown, Github } from 'lucide-react';
function Header() {
const [isMenuOpen, setIsMenuOpen] = useState(false);
const [isResourcesOpen, setIsResourcesOpen] = useState(false);
return (
<header className="fixed top-0 left-0 right-0 z-50 bg-black/90 backdrop-blur-sm">
<div className="container-custom">
<div className="flex items-center justify-between h-16">
{/* Logo */}
<div className="flex items-center">
<img
src="https://nestjs.com/img/logo-small.svg"
alt="NestJS"
className="h-8 w-8"
/>
</div>
{/* Desktop Navigation */}
<nav className="hidden md:flex items-center space-x-8">
<a href="#" className="text-white hover:text-nest-red transition-colors">
DOCUMENTATION
</a>
<a href="#" className="text-white hover:text-nest-red transition-colors">
ENTERPRISE
</a>
<div className="relative">
<button
className="flex items-center text-white hover:text-nest-red transition-colors"
onClick={() => setIsResourcesOpen(!isResourcesOpen)}
>
<span className="bg-nest-red text-white text-xs px-2 py-1 rounded mr-2">
NEW
</span>
RESOURCES
<ChevronDown className="ml-1 h-4 w-4" />
</button>
</div>
</nav>
{/* Social Links */}
<div className="hidden md:flex items-center space-x-4">
<a href="#" className="text-white hover:text-nest-red transition-colors">
<Github className="h-5 w-5" />
</a>
<a href="#" className="text-white hover:text-nest-red transition-colors">
<X className="h-5 w-5" />
</a>
<a href="#" className="text-white hover:text-nest-red transition-colors">
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</a>
</div>
{/* Mobile menu button */}
<button
className="md:hidden text-white"
onClick={() => setIsMenuOpen(!isMenuOpen)}
>
{isMenuOpen ? <X className="h-6 w-6" /> : <Menu className="h-6 w-6" />}
</button>
</div>
{/* Mobile Navigation */}
{isMenuOpen && (
<div className="md:hidden bg-black/95 absolute top-16 left-0 right-0 p-4">
<nav className="flex flex-col space-y-4">
<a href="#" className="text-white hover:text-nest-red transition-colors">
DOCUMENTATION
</a>
<a href="#" className="text-white hover:text-nest-red transition-colors">
ENTERPRISE
</a>
<a href="#" className="text-white hover:text-nest-red transition-colors">
RESOURCES
</a>
</nav>
</div>
)}
</div>
</header>
);
}
export default Header;

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

@@ -0,0 +1,82 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
import { Github } 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" }
});
function 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-cover bg-center bg-no-repeat opacity-30"
style={{ backgroundImage: "url('https://nestjs.com/img/hero-bg.jpg')" }}
/>
<div className="relative z-10 container-custom text-center text-white">
<h1 className="text-5xl md:text-7xl font-bold mb-6">
Hello, nest!
</h1>
<p className="text-xl md:text-2xl mb-12 max-w-3xl mx-auto leading-relaxed">
A progressive Node.js framework for building efficient, reliable and scalable server-side applications.
</p>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<button className="btn-primary text-lg px-8 py-4">
Documentation
</button>
<button className="btn-secondary text-lg px-8 py-4 flex items-center justify-center gap-2">
<Github className="h-5 w-5" />
Source code
</button>
</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-cover bg-center bg-no-repeat opacity-30"
style={{ backgroundImage: "url('https://nestjs.com/img/hero-bg.jpg')" }}
/>
<div className="relative z-10 container-custom text-center text-white">
<motion.h1
{...fadeUpPreset(0.2, 0.8)}
className="text-5xl md:text-7xl font-bold mb-6"
>
Hello, nest!
</motion.h1>
<motion.p
{...fadeUpPreset(0.4, 0.8)}
className="text-xl md:text-2xl mb-12 max-w-3xl mx-auto leading-relaxed"
>
A progressive Node.js framework for building efficient, reliable and scalable server-side applications.
</motion.p>
<motion.div
{...fadeUpPreset(0.6, 0.8)}
className="flex flex-col sm:flex-row gap-4 justify-center"
>
<button className="btn-primary text-lg px-8 py-4">
Documentation
</button>
<button className="btn-secondary text-lg px-8 py-4 flex items-center justify-center gap-2">
<Github className="h-5 w-5" />
Source code
</button>
</motion.div>
</div>
</motion.section>
);
}
export default Hero;

View File

@@ -0,0 +1,99 @@
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" }
});
function LivePreview() {
const shouldReduce = useReducedMotion();
if (shouldReduce) {
return (
<section className="section-padding bg-nest-dark text-white">
<div className="container-custom text-center">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Live preview
</h2>
<p className="text-xl text-gray-300 mb-12 max-w-2xl mx-auto">
See NestJS in action with our interactive examples and live coding environment.
</p>
<div className="bg-black/50 rounded-lg p-8 max-w-4xl mx-auto">
<div className="text-left">
<div className="flex items-center gap-2 mb-4">
<div className="w-3 h-3 bg-red-500 rounded-full"></div>
<div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div className="font-mono text-sm text-gray-300">
<div className="text-blue-400">import</div>
<div className="ml-4">{'{ Controller, Get }'} <span className="text-blue-400">from</span> <span className="text-green-400">'@nestjs/common'</span>;</div>
<div className="mt-4 text-yellow-400">@Controller()</div>
<div className="text-blue-400">export class</div>
<div className="ml-4">AppController {'{'}</div>
<div className="ml-8 text-yellow-400">@Get()</div>
<div className="ml-8">getHello(): <span className="text-blue-400">string</span> {'{'}</div>
<div className="ml-12 text-blue-400">return</div>
<div className="ml-16 text-green-400">'Hello World!'</div>
<div className="ml-8">{'}'}</div>
<div className="ml-4">{'}'}</div>
</div>
</div>
</div>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-nest-dark text-white"
>
<div className="container-custom text-center">
<motion.h2
{...fadeUpPreset(0.2, 0.8)}
className="text-4xl md:text-5xl font-bold mb-6"
>
Live preview
</motion.h2>
<motion.p
{...fadeUpPreset(0.3, 0.8)}
className="text-xl text-gray-300 mb-12 max-w-2xl mx-auto"
>
See NestJS in action with our interactive examples and live coding environment.
</motion.p>
<motion.div
{...fadeUpPreset(0.4, 0.8)}
className="bg-black/50 rounded-lg p-8 max-w-4xl mx-auto"
>
<div className="text-left">
<div className="flex items-center gap-2 mb-4">
<div className="w-3 h-3 bg-red-500 rounded-full"></div>
<div className="w-3 h-3 bg-yellow-500 rounded-full"></div>
<div className="w-3 h-3 bg-green-500 rounded-full"></div>
</div>
<div className="font-mono text-sm text-gray-300">
<div className="text-blue-400">import</div>
<div className="ml-4">{'{ Controller, Get }'} <span className="text-blue-400">from</span> <span className="text-green-400">'@nestjs/common'</span>;</div>
<div className="mt-4 text-yellow-400">@Controller()</div>
<div className="text-blue-400">export class</div>
<div className="ml-4">AppController {'{'}</div>
<div className="ml-8 text-yellow-400">@Get()</div>
<div className="ml-8">getHello(): <span className="text-blue-400">string</span> {'{'}</div>
<div className="ml-12 text-blue-400">return</div>
<div className="ml-16 text-green-400">'Hello World!'</div>
<div className="ml-8">{'}'}</div>
<div className="ml-4">{'}'}</div>
</div>
</div>
</motion.div>
</div>
</motion.section>
);
}
export default LivePreview;

View File

@@ -0,0 +1,120 @@
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" }
});
function SupportSection() {
const shouldReduce = useReducedMotion();
const supportOptions = [
{
title: "PRINCIPAL SPONSORS",
items: ["Valor Software", "Adyen", "Sanofi"]
},
{
title: "GOLD SPONSORS",
items: ["Trilon", "Amplication"]
},
{
title: "SILVER SPONSORS",
items: ["Nx", "Sentry", "JetBrains"]
},
{
title: "SPONSORS / PARTNERS",
items: ["Various Partners"]
}
];
if (shouldReduce) {
return (
<section className="section-padding bg-white">
<div className="container-custom text-center">
<h2 className="text-4xl md:text-5xl font-bold mb-6">
Support us
</h2>
<p className="text-xl text-nest-gray mb-16 max-w-3xl mx-auto">
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
</p>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8 mb-12">
{supportOptions.map((option, index) => (
<div key={index} className="text-center">
<h3 className="font-bold text-sm text-nest-red mb-4">
{option.title}
</h3>
<div className="space-y-2">
{option.items.map((item, itemIndex) => (
<div key={itemIndex} className="text-nest-gray text-sm">
{item}
</div>
))}
</div>
</div>
))}
</div>
<button className="btn-primary">
Become a sponsor
</button>
</div>
</section>
);
}
return (
<motion.section
{...fadeUpPreset(0.1, 1.0)}
className="section-padding bg-white"
>
<div className="container-custom text-center">
<motion.h2
{...fadeUpPreset(0.2, 0.8)}
className="text-4xl md:text-5xl font-bold mb-6"
>
Support us
</motion.h2>
<motion.p
{...fadeUpPreset(0.3, 0.8)}
className="text-xl text-nest-gray mb-16 max-w-3xl mx-auto"
>
Nest is an MIT-licensed open source project. It can grow thanks to the sponsors and support by the amazing backers. If you'd like to join them, please read more here.
</motion.p>
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8 mb-12">
{supportOptions.map((option, index) => (
<motion.div
key={index}
{...fadeUpPreset(0.4 + (index * 0.1), 0.6)}
className="text-center"
>
<h3 className="font-bold text-sm text-nest-red mb-4">
{option.title}
</h3>
<div className="space-y-2">
{option.items.map((item, itemIndex) => (
<div key={itemIndex} className="text-nest-gray text-sm">
{item}
</div>
))}
</div>
</motion.div>
))}
</div>
<motion.button
{...fadeUpPreset(0.8, 0.6)}
className="btn-primary"
>
Become a sponsor
</motion.button>
</div>
</motion.section>
);
}
export default SupportSection;

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-gray-900;
}
}
@layer components {
.btn-primary {
@apply bg-nest-red text-white px-6 py-3 rounded-lg font-medium hover:bg-red-600 transition-colors duration-200;
}
.btn-secondary {
@apply border border-white text-white px-6 py-3 rounded-lg font-medium hover:bg-white hover:text-gray-900 transition-colors duration-200;
}
.feature-card {
@apply bg-white p-8 rounded-lg shadow-sm hover:shadow-md transition-shadow 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;
}
}

8
src/index.js Normal file
View File

@@ -0,0 +1,8 @@
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(<App />);