- Programming Fundamentals
- JavaScript/TypeScript Basics
- React Fundamentals
- Next.js Framework
- Project Architecture
- State Management
- API Development
- Database Operations
- Authentication
- Styling & UI
- Performance Optimization
- Error Handling
// Basic Variable Declarations
let name: string = "John"; // String
let age: number = 25; // Number (integer)
let height: number = 5.9; // Number (float)
let isStudent: boolean = true; // Boolean
let scores: number[] = [85, 92, 78]; // Array
let person: object = { name: "John", age: 25 }; // Object
// Constants
const PI: number = 3.14159;
const MAX_SIZE: number = 100;
// Union Types
let value: string | number = "hello";
value = 42; // Valid
// Any Type (avoid when possible)
let data: any = "could be anything";// Interface Definition
interface User {
id: number;
name: string;
email: string;
age?: number; // Optional property
readonly createdAt: Date; // Read-only property
}
// Type Alias
type Status = 'active' | 'inactive' | 'pending';
type ApiResponse<T> = {
success: boolean;
data?: T;
error?: string;
};
// Generic Interface
interface Repository<T> {
findAll(): T[];
findById(id: number): T | undefined;
create(item: T): T;
update(id: number, item: T): T | undefined;
delete(id: number): boolean;
}// Conditional Statements
if (age >= 18) {
console.log("Adult");
} else if (age >= 13) {
console.log("Teenager");
} else {
console.log("Child");
}
// Switch Statement
switch (status) {
case 'active':
console.log("User is active");
break;
case 'inactive':
console.log("User is inactive");
break;
default:
console.log("Unknown status");
}
// Loops
for (let i = 0; i < scores.length; i++) {
console.log(`Score ${i + 1}: ${scores[i]}`);
}
scores.forEach((score, index) => {
console.log(`Score ${index + 1}: ${score}`);
});
while (count < 10) {
count++;
}
do {
count--;
} while (count > 0);// Function Declaration
function add(a: number, b: number): number {
return a + b;
}
// Arrow Function
const multiply = (a: number, b: number): number => a * b;
// Optional Parameters
function greet(name: string, greeting?: string): string {
return `${greeting || 'Hello'}, ${name}!`;
}
// Default Parameters
function createUser(name: string, role: string = 'user'): User {
return { id: Date.now(), name, email: '', createdAt: new Date() };
}
// Rest Parameters
function sum(...numbers: number[]): number {
return numbers.reduce((total, num) => total + num, 0);
}// Destructuring
const user = { name: 'John', age: 25, email: '[email protected]' };
const { name, age } = user;
// Array Destructuring
const [first, second, ...rest] = scores;
// Spread Operator
const newUser = { ...user, role: 'admin' };
const allScores = [...scores, 95, 88];
// Template Literals
const message = `Hello, ${name}! You are ${age} years old.`;
// Promises
const fetchData = (): Promise<User[]> => {
return new Promise((resolve, reject) => {
// Async operation
setTimeout(() => {
resolve([{ id: 1, name: 'John', email: '[email protected]' }]);
}, 1000);
});
};
// Async/Await
const getUsers = async (): Promise<User[]> => {
try {
const users = await fetchData();
return users;
} catch (error) {
console.error('Error fetching users:', error);
throw error;
}
};// Class Definition
class Person {
private id: number;
protected name: string;
public age: number;
constructor(id: number, name: string, age: number) {
this.id = id;
this.name = name;
this.age = age;
}
// Method
greet(): string {
return `Hello, I'm ${this.name}`;
}
// Getter
get personId(): number {
return this.id;
}
// Setter
set personName(newName: string) {
this.name = newName;
}
}
// Inheritance
class Employee extends Person {
private department: string;
constructor(id: number, name: string, age: number, department: string) {
super(id, name, age);
this.department = department;
}
// Override method
greet(): string {
return `${super.greet()} and I work in ${this.department}`;
}
}// Export (lib/auth.ts)
export const authOptions = { /* ... */ };
export function connectToDatabase() { /* ... */ };
// Import
import { authOptions, connectToDatabase } from '../lib/auth';
import * as AuthModule from '../lib/auth';
// Default Export
export default function AuthProvider() { /* ... */ }
// Default Import
import AuthProvider from '../components/AuthProvider';// Functional Component
const Welcome: React.FC<{ name: string }> = ({ name }) => {
return <h1>Hello, {name}!</h1>;
};
// Arrow Function Component
const Button: React.FC<{ onClick: () => void; children: React.ReactNode }> = ({
onClick,
children
}) => (
<button onClick={onClick} className="btn-primary">
{children}
</button>
);
// Class Component (Legacy)
class Counter extends React.Component<
{ initialCount?: number },
{ count: number }
> {
constructor(props: { initialCount?: number }) {
super(props);
this.state = { count: props.initialCount || 0 };
}
increment = () => {
this.setState({ count: this.state.count + 1 });
};
render() {
return (
<div>
<p>Count: {this.state.count}</p>
<button onClick={this.increment}>Increment</button>
</div>
);
}
}// Props Interface
interface ProductCardProps {
product: Product;
onAddToCart?: (productId: string) => void;
className?: string;
}
// Component with Props
const ProductCard: React.FC<ProductCardProps> = ({
product,
onAddToCart,
className = ''
}) => {
const [isHovered, setIsHovered] = React.useState(false);
return (
<div
className={`product-card ${className} ${isHovered ? 'hovered' : ''}`}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<h3>{product.title}</h3>
<p>₹{product.price}</p>
{onAddToCart && (
<button onClick={() => onAddToCart(product.id!)}>
Add to Cart
</button>
)}
</div>
);
};// useState Hook
const [count, setCount] = React.useState<number>(0);
const [user, setUser] = React.useState<User | null>(null);
// useEffect Hook
React.useEffect(() => {
// Component did mount
fetchUser();
// Cleanup function
return () => {
// Component will unmount
console.log('Component unmounting');
};
}, []); // Empty dependency array = run once
// useEffect with dependencies
React.useEffect(() => {
// Run when user changes
console.log('User updated:', user);
}, [user]);
// Custom Hook
const useLocalStorage = <T,>(key: string, initialValue: T) => {
const [storedValue, setStoredValue] = React.useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
return initialValue;
}
});
const setValue = (value: T) => {
try {
setStoredValue(value);
window.localStorage.setItem(key, JSON.stringify(value));
} catch (error) {
console.error(error);
}
};
return [storedValue, setValue] as const;
};// Event Handler Types
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
event.preventDefault();
console.log('Button clicked');
};
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setValue(event.target.value);
};
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
// Form submission logic
};
// Keyboard Events
const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key === 'Enter') {
handleSubmit();
}
};// src/app/layout.tsx - Root Layout (Server Component)
import type { Metadata } from "next";
import { Geist, Ubuntu } from "next/font/google";
const geistSans = Geist({
variable: "--font-geist-sans",
subsets: ["latin"],
});
export const metadata: Metadata = {
title: "PaniPonics",
description: "Vertical Gardening towers for home-grown greens",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={`${geistSans.variable} ${ubuntu.variable} antialiased`}>
<AuthProvider>
<CartProvider>
<AppShell>{children}</AppShell>
</CartProvider>
</AuthProvider>
</body>
</html>
);
}// src/app/page.tsx - Home Page
export default function HomePage() {
return (
<div>
<Hero />
<StatCards />
<OurServices />
</div>
);
}
// src/app/store/page.tsx - Store Page
export default function StorePage() {
return (
<div className="container mx-auto">
<h1>Our Products</h1>
{/* Product listing */}
</div>
);
}
// src/app/store/[id]/page.tsx - Dynamic Product Page
interface ProductPageProps {
params: { id: string };
}
export default function ProductPage({ params }: ProductPageProps) {
return (
<div>
<h1>Product {params.id}</h1>
{/* Product details */}
</div>
);
}// src/app/api/products/route.ts - REST API
import { NextRequest, NextResponse } from "next/server";
export async function GET(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const category = searchParams.get('category');
// Fetch products logic
const products = await getProducts(category);
return NextResponse.json(products);
} catch (error) {
return NextResponse.json(
{ error: 'Failed to fetch products' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// Validate required fields
if (!body.title || !body.price) {
return NextResponse.json(
{ error: 'Title and price are required' },
{ status: 400 }
);
}
// Create product logic
const product = await createProduct(body);
return NextResponse.json(product, { status: 201 });
} catch (error) {
return NextResponse.json(
{ error: 'Failed to create product' },
{ status: 500 }
);
}
}// Server Component (Default)
async function ProductList() {
// This runs on the server
const products = await fetchProducts();
return (
<div>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</div>
);
}
// Client Component
'use client';
import { useState } from 'react';
function InteractiveProductCard({ product }: { product: Product }) {
const [isLiked, setIsLiked] = useState(false);
// This runs on the client
const handleLike = () => {
setIsLiked(!isLiked);
// API call to like product
};
return (
<div>
<ProductCard product={product} />
<button onClick={handleLike}>
{isLiked ? '❤️' : '🤍'} Like
</button>
</div>
);
}// src/components/AppShell.tsx - Layout Wrapper
'use client';
import { useState } from 'react';
import SiteHeader from './SiteHeader';
import CartSidebar from './CartSidebar';
import AuthModal from './AuthModal';
export default function AppShell({ children }: { children: React.ReactNode }) {
const [authOpen, setAuthOpen] = useState(false);
return (
<>
<SiteHeader onOpenAuth={() => setAuthOpen(true)} />
<CartSidebar />
<main className="app-content">{children}</main>
{authOpen && <AuthModal onClose={() => setAuthOpen(false)} />}
</>
);
}// src/context/CartContext.tsx - Global State Management
'use client';
import { createContext, useContext, useState, useEffect } from 'react';
type CartItem = Product & { qty: number };
type CartContextType = {
items: CartItem[];
addItem: (product: Product, qty?: number) => void;
removeItem: (id: string) => void;
clearCart: () => void;
totalItems: () => number;
totalAmount: () => number;
};
const CartContext = createContext<CartContextType | null>(null);
export function CartProvider({ children }: { children: React.ReactNode }) {
const [items, setItems] = useState<CartItem[]>([]);
// Load from localStorage
useEffect(() => {
const stored = localStorage.getItem('cart');
if (stored) {
setItems(JSON.parse(stored));
}
}, []);
// Save to localStorage
useEffect(() => {
localStorage.setItem('cart', JSON.stringify(items));
}, [items]);
const addItem = (product: Product, qty = 1) => {
setItems(current => {
const existing = current.find(item => item.id === product.id);
if (existing) {
return current.map(item =>
item.id === product.id
? { ...item, qty: item.qty + qty }
: item
);
}
return [...current, { ...product, qty }];
});
};
return (
<CartContext.Provider value={{
items,
addItem,
removeItem: (id) => setItems(current => current.filter(item => item.id !== id)),
clearCart: () => setItems([]),
totalItems: () => items.reduce((sum, item) => sum + item.qty, 0),
totalAmount: () => items.reduce((sum, item) => sum + (item.price * item.qty), 0)
}}>
{children}
</CartContext.Provider>
);
}
export function useCart() {
const context = useContext(CartContext);
if (!context) {
throw new Error('useCart must be used within CartProvider');
}
return context;
}// src/types/products.ts - Product Types
export type Product = {
id?: string;
_id?: string;
title?: string;
heading?: string;
description?: string;
price?: number | string;
amount?: number;
images?: string[];
img?: string;
image?: string;
imageUrl?: string;
weight_kg?: number;
freeShipping?: boolean;
inventory?: number;
createdAt?: string;
[key: string]: any; // Allow additional fields
};
// Cart-specific types
export type CartProduct = Pick<Product,
| 'id' | 'title' | 'price' | 'amount' | 'images'
| 'img' | 'image' | 'imageUrl' | 'weight_kg'
| 'freeShipping' | 'inventory'
>;
export type AddToCartProduct = CartProduct;// Advanced Context with useReducer
type CartAction =
| { type: 'ADD_ITEM'; payload: { product: Product; qty: number } }
| { type: 'REMOVE_ITEM'; payload: { id: string } }
| { type: 'UPDATE_QTY'; payload: { id: string; qty: number } }
| { type: 'CLEAR_CART' };
const cartReducer = (state: CartState, action: CartAction): CartState => {
switch (action.type) {
case 'ADD_ITEM':
// Implementation
return newState;
case 'REMOVE_ITEM':
return { ...state, items: state.items.filter(item => item.id !== action.payload.id) };
default:
return state;
}
};
export function CartProvider({ children }: { children: React.ReactNode }) {
const [state, dispatch] = useReducer(cartReducer, initialState);
return (
<CartContext.Provider value={{ state, dispatch }}>
{children}
</CartContext.Provider>
);
}// src/hooks/useLocalStorage.ts
export function useLocalStorage<T>(key: string, initialValue: T) {
const [storedValue, setStoredValue] = useState<T>(() => {
try {
const item = window.localStorage.getItem(key);
return item ? JSON.parse(item) : initialValue;
} catch (error) {
console.error('Error reading localStorage:', error);
return initialValue;
}
});
const setValue = useCallback((value: T | ((val: T) => T)) => {
try {
const valueToStore = value instanceof Function ? value(storedValue) : value;
setStoredValue(valueToStore);
window.localStorage.setItem(key, JSON.stringify(valueToStore));
} catch (error) {
console.error('Error setting localStorage:', error);
}
}, [key, storedValue]);
return [storedValue, setValue] as const;
}
// src/hooks/useApi.ts
export function useApi<T>(url: string) {
const [data, setData] = useState<T | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchData = async () => {
try {
setLoading(true);
const response = await fetch(url);
if (!response.ok) throw new Error('API Error');
const result = await response.json();
setData(result);
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error');
} finally {
setLoading(false);
}
};
fetchData();
}, [url]);
return { data, loading, error };
}// src/app/api/products/route.ts - Complete CRUD API
import { NextRequest, NextResponse } from "next/server";
import { connectToDatabase } from "../../../lib/mongodb";
import { ObjectId } from "mongodb";
export async function GET(request: NextRequest) {
try {
const { db } = await connectToDatabase();
const { searchParams } = new URL(request.url);
const limit = parseInt(searchParams.get('limit') || '10');
const skip = parseInt(searchParams.get('skip') || '0');
const category = searchParams.get('category');
let query = {};
if (category) {
query = { category };
}
const products = await db
.collection("products")
.find(query)
.limit(limit)
.skip(skip)
.sort({ createdAt: -1 })
.toArray();
const total = await db.collection("products").countDocuments(query);
return NextResponse.json({
products,
pagination: { total, limit, skip, hasMore: skip + limit < total }
});
} catch (error) {
return NextResponse.json(
{ error: 'Failed to fetch products' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { db } = await connectToDatabase();
// Validate required fields
if (!body.title || !body.price) {
return NextResponse.json(
{ error: 'Title and price are required' },
{ status: 400 }
);
}
// Create product with timestamp
const product = {
...body,
createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString()
};
const result = await db.collection("products").insertOne(product);
return NextResponse.json(
{ ...product, _id: result.insertedId },
{ status: 201 }
);
} catch (error) {
return NextResponse.json(
{ error: 'Failed to create product' },
{ status: 500 }
);
}
}// src/app/api/products/[id]/route.ts - Dynamic Route
import { NextRequest, NextResponse } from "next/server";
import { connectToDatabase } from "../../../../lib/mongodb";
import { ObjectId } from "mongodb";
interface RouteParams {
params: { id: string };
}
export async function GET(request: NextRequest, { params }: RouteParams) {
try {
const { db } = await connectToDatabase();
const { id } = params;
let objectId;
try {
objectId = new ObjectId(id);
} catch {
return NextResponse.json(
{ error: 'Invalid product ID' },
{ status: 400 }
);
}
const product = await db.collection("products").findOne({ _id: objectId });
if (!product) {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
return NextResponse.json(product);
} catch (error) {
return NextResponse.json(
{ error: 'Failed to fetch product' },
{ status: 500 }
);
}
}
export async function PUT(request: NextRequest, { params }: RouteParams) {
try {
const body = await request.json();
const { db } = await connectToDatabase();
const { id } = params;
let objectId;
try {
objectId = new ObjectId(id);
} catch {
return NextResponse.json(
{ error: 'Invalid product ID' },
{ status: 400 }
);
}
const updateData = {
...body,
updatedAt: new Date().toISOString()
};
// Remove undefined fields
Object.keys(updateData).forEach(key =>
updateData[key] === undefined && delete updateData[key]
);
const result = await db.collection("products").updateOne(
{ _id: objectId },
{ $set: updateData }
);
if (result.matchedCount === 0) {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json(
{ error: 'Failed to update product' },
{ status: 500 }
);
}
}
export async function DELETE(request: NextRequest, { params }: RouteParams) {
try {
const { db } = await connectToDatabase();
const { id } = params;
let objectId;
try {
objectId = new ObjectId(id);
} catch {
return NextResponse.json(
{ error: 'Invalid product ID' },
{ status: 400 }
);
}
const result = await db.collection("products").deleteOne({ _id: objectId });
if (result.deletedCount === 0) {
return NextResponse.json(
{ error: 'Product not found' },
{ status: 404 }
);
}
return NextResponse.json({ success: true });
} catch (error) {
return NextResponse.json(
{ error: 'Failed to delete product' },
{ status: 500 }
);
}
}// src/lib/mongodb.ts - Database Connection
import { MongoClient, Db } from 'mongodb';
const MONGODB_URI = process.env.MONGODB_URI!;
const MONGODB_DB = process.env.MONGODB_DB!;
interface DatabaseConnection {
client: MongoClient;
db: Db;
}
let cachedClient: MongoClient | null = null;
let cachedDb: Db | null = null;
export async function connectToDatabase(): Promise<DatabaseConnection> {
// Return cached connection if available
if (cachedClient && cachedDb) {
return { client: cachedClient, db: cachedDb };
}
try {
// Create new connection
const client = await MongoClient.connect(MONGODB_URI, {
maxPoolSize: 10, // Connection pool size
serverSelectionTimeoutMS: 5000, // Timeout for server selection
socketTimeoutMS: 45000, // Socket timeout
});
const db = client.db(MONGODB_DB);
// Cache the connection
cachedClient = client;
cachedDb = db;
return { client, db };
} catch (error) {
console.error('Failed to connect to database:', error);
throw new Error('Database connection failed');
}
}// Complex queries and aggregations
export async function getProductAnalytics() {
const { db } = await connectToDatabase();
const pipeline = [
{
$group: {
_id: '$category',
totalProducts: { $sum: 1 },
averagePrice: { $avg: '$price' },
totalInventory: { $sum: '$inventory' },
products: { $push: '$$ROOT' }
}
},
{
$sort: { totalProducts: -1 }
}
];
const results = await db.collection('products').aggregate(pipeline).toArray();
return results;
}
// Transaction example
export async function transferInventory(
fromProductId: string,
toProductId: string,
quantity: number
) {
const { client, db } = await connectToDatabase();
const session = client.startSession();
try {
await session.withTransaction(async () => {
// Check if source has enough inventory
const sourceProduct = await db.collection('products').findOne(
{ _id: new ObjectId(fromProductId), inventory: { $gte: quantity } },
{ session }
);
if (!sourceProduct) {
throw new Error('Insufficient inventory');
}
// Update source inventory
await db.collection('products').updateOne(
{ _id: new ObjectId(fromProductId) },
{ $inc: { inventory: -quantity } },
{ session }
);
// Update destination inventory
await db.collection('products').updateOne(
{ _id: new ObjectId(toProductId) },
{ $inc: { inventory: quantity } },
{ session }
);
// Log the transfer
await db.collection('inventory_transfers').insertOne({
fromProductId,
toProductId,
quantity,
timestamp: new Date()
}, { session });
});
return { success: true };
} catch (error) {
return { success: false, error: error.message };
} finally {
await session.endSession();
}
}// src/lib/auth.ts - Complete Auth Setup
import type { AuthOptions, Session } from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import CredentialsProvider from "next-auth/providers/credentials";
import { connectToDatabase } from "./mongodb";
import { scryptSync } from "crypto";
export const authOptions: AuthOptions = {
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID!,
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
}),
CredentialsProvider({
name: "credentials",
credentials: {
email: { label: "Email", type: "email" },
password: { label: "Password", type: "password" }
},
async authorize(credentials) {
if (!credentials?.email || !credentials?.password) {
return null;
}
try {
const { db } = await connectToDatabase();
const user = await db.collection("users").findOne({
email: credentials.email
});
if (!user || !user.password) {
return null;
}
// Verify password (using scrypt for security)
const [salt, key] = user.password.split(":");
const derivedKey = scryptSync(credentials.password, salt, 64);
const derivedKeyHex = derivedKey.toString("hex");
if (derivedKeyHex !== key) {
return null;
}
return {
id: user._id.toString(),
email: user.email,
name: user.name,
image: user.image
};
} catch (error) {
console.error("Authentication error:", error);
return null;
}
}
})
],
session: {
strategy: "jwt",
maxAge: 30 * 24 * 60 * 60, // 30 days
},
secret: process.env.NEXTAUTH_SECRET,
pages: {
signIn: "/auth/signin",
signUp: "/auth/signup",
error: "/auth/error"
},
callbacks: {
async jwt({ token, user }) {
if (user) {
token.id = user.id;
}
return token;
},
async session({ session, token }) {
if (token) {
session.user.id = token.id as string;
}
return session;
},
async signIn({ user, account, profile }) {
if (account?.provider === "google") {
try {
const { db } = await connectToDatabase();
// Upsert Google user
await db.collection("users").updateOne(
{ email: user.email },
{
$set: {
name: user.name,
email: user.email,
image: user.image,
googleId: profile?.sub,
updatedAt: new Date()
}
},
{ upsert: true }
);
} catch (error) {
console.error("Error saving Google user:", error);
return false;
}
}
return true;
}
}
};
export default authOptions;// src/components/AuthProvider.tsx
'use client';
import { SessionProvider } from 'next-auth/react';
export default function AuthProvider({
children,
session
}: {
children: React.ReactNode;
session?: any;
}) {
return (
<SessionProvider session={session}>
{children}
</SessionProvider>
);
}// tailwind.config.mjs
export default {
content: [
"./src/**/*.{js,ts,jsx,tsx,mdx}",
"./app/**/*.{js,ts,jsx,tsx,mdx}",
"./components/**/*.{js,ts,jsx,tsx,mdx}"
],
theme: {
extend: {
colors: {
primary: "var(--color-primary)",
"primary-600": "var(--color-primary-600)",
"primary-400": "var(--color-primary-400)",
success: "var(--color-success)",
warning: "var(--color-warning)",
error: "var(--color-error)"
},
fontFamily: {
sans: ["var(--font-geist-sans)", "system-ui", "sans-serif"],
mono: ["var(--font-geist-mono)", "monospace"],
ubuntu: ["var(--font-ubuntu)", "sans-serif"]
},
animation: {
'fade-in': 'fadeIn 0.5s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
'bounce-slow': 'bounce 2s infinite'
}
}
},
plugins: []
}// src/components/Hero.tsx - Responsive Component
'use client';
import { useState, useEffect } from 'react';
export default function Hero() {
const [isExpanded, setIsExpanded] = useState(true);
const [isMobile, setIsMobile] = useState(false);
useEffect(() => {
const checkMobile = () => {
const mobile = window.innerWidth < 1024;
setIsMobile(mobile);
if (!mobile) {
setIsExpanded(true);
}
};
checkMobile();
window.addEventListener('resize', checkMobile);
return () => window.removeEventListener('resize', checkMobile);
}, []);
return (
<section className="relative">
<div className="max-w-6xl mx-auto flex flex-col lg:flex-row items-center gap-8">
{/* Content */}
<div className="lg:w-1/2">
<h1 className="text-4xl md:text-5xl lg:text-6xl font-bold leading-tight">
<span className="block bg-gradient-to-r from-cyan-500 to-blue-300 bg-clip-text text-transparent">
Grow Fresh, Grow Smart
</span>
</h1>
{/* Mobile expandable content */}
<div className="lg:hidden">
<div
className={`transition-all duration-500 ease-out overflow-hidden ${
isExpanded ? 'max-h-96 opacity-100' : 'max-h-20 opacity-90'
}`}
>
<p>Content that expands on mobile...</p>
</div>
<button
onClick={() => setIsExpanded(!isExpanded)}
className="mt-2 text-primary-600 font-semibold"
>
{isExpanded ? 'Read less' : 'Read more'}
</button>
</div>
</div>
{/* Image */}
<div className="lg:w-1/2">
<div className="relative w-full max-w-md mx-auto">
<Image
src="/Images/hero.jpg"
alt="PaniPonics Tower"
width={400}
height={400}
className="w-full h-auto rounded-2xl shadow-2xl"
priority
/>
</div>
</div>
</div>
</section>
);
}// src/components/AnimatedSection.tsx
'use client';
import { motion } from 'framer-motion';
import { useInView } from 'react-intersection-observer';
interface AnimatedSectionProps {
children: React.ReactNode;
className?: string;
delay?: number;
}
export default function AnimatedSection({
children,
className = '',
delay = 0
}: AnimatedSectionProps) {
const [ref, inView] = useInView({
triggerOnce: true,
threshold: 0.1
});
const variants = {
hidden: { opacity: 0, y: 50 },
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.6,
delay,
ease: "easeOut"
}
}
};
return (
<motion.div
ref={ref}
initial="hidden"
animate={inView ? "visible" : "hidden"}
variants={variants}
className={className}
>
{children}
</motion.div>
);
}// Next.js Image component patterns
import Image from 'next/image';
export default function OptimizedImages() {
return (
<div>
{/* Local image with priority (above fold) */}
<Image
src="/Images/hero.jpg"
alt="Hero image"
width={800}
height={600}
priority // Loads immediately
className="w-full h-auto"
/>
{/* Remote image with loading optimization */}
<Image
src="https://example.com/image.jpg"
alt="Remote image"
width={400}
height={300}
loading="lazy" // Loads when near viewport
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
{/* Responsive image */}
<Image
src="/Images/product.jpg"
alt="Product"
fill // Fills parent container
className="object-cover"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
);
}// Dynamic imports for code splitting
const AdminPanel = lazy(() => import('../components/AdminPanel'));
const ChartComponent = lazy(() => import('../components/Chart'));
// Component with lazy loading
function Dashboard() {
const [showChart, setShowChart] = useState(false);
return (
<div>
<button onClick={() => setShowChart(true)}>
Show Chart
</button>
{showChart && (
<Suspense fallback={<div>Loading chart...</div>}>
<ChartComponent />
</Suspense>
)}
</div>
);
}// src/lib/performance.ts
export function measurePerformance(name: string, fn: () => void | Promise<void>) {
const start = performance.now();
const result = fn();
if (result instanceof Promise) {
return result.finally(() => {
const end = performance.now();
console.log(`${name} took ${end - start} milliseconds`);
});
} else {
const end = performance.now();
console.log(`${name} took ${end - start} milliseconds`);
}
}
// Usage
await measurePerformance('Database Query', async () => {
const products = await fetchProducts();
setProducts(products);
});// src/components/ErrorBoundary.tsx
'use client';
import React from 'react';
interface ErrorBoundaryState {
hasError: boolean;
error?: Error;
}
interface ErrorBoundaryProps {
children: React.ReactNode;
fallback?: React.ComponentType<{ error?: Error; resetError: () => void }>;
}
class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
constructor(props: ErrorBoundaryProps) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
return { hasError: true, error };
}
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
console.error('Error caught by boundary:', error, errorInfo);
// Report to error tracking service
reportError(error, errorInfo);
}
resetError = () => {
this.setState({ hasError: false, error: undefined });
};
render() {
if (this.state.hasError) {
const FallbackComponent = this.props.fallback || DefaultErrorFallback;
return (
<FallbackComponent
error={this.state.error}
resetError={this.resetError}
/>
);
}
return this.props.children;
}
}
function DefaultErrorFallback({ error, resetError }: { error?: Error; resetError: () => void }) {
return (
<div className="error-fallback">
<h2>Something went wrong</h2>
<p>{error?.message || 'An unexpected error occurred'}</p>
<button onClick={resetError}>Try again</button>
</div>
);
}// src/lib/api-client.ts
export class ApiError extends Error {
constructor(
message: string,
public status: number,
public data?: any
) {
super(message);
this.name = 'ApiError';
}
}
export async function apiRequest<T>(
url: string,
options: RequestInit = {}
): Promise<T> {
try {
const response = await fetch(url, {
headers: {
'Content-Type': 'application/json',
...options.headers
},
...options
});
if (!response.ok) {
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
let errorData;
try {
errorData = await response.json();
errorMessage = errorData.error || errorMessage;
} catch {
// Response is not JSON
}
throw new ApiError(errorMessage, response.status, errorData);
}
return await response.json();
} catch (error) {
if (error instanceof ApiError) {
throw error;
}
// Network or other error
throw new ApiError(
error instanceof Error ? error.message : 'Network error',
0
);
}
}This comprehensive cheat sheet covers everything from basic programming concepts to advanced Next.js patterns used in the PaniPhonics project. Use it as a complete reference for understanding modern web development with React, Next.js, and TypeScript.