Summary
Highlights
This section outlines the `Pins` container, which serves as the central hub for displaying content. It integrates `Navbar`, `Feed`, `PinDetail`, `CreatePin`, and `Search` components. Dynamic routes are set up for categories, pin details, creating pins, and search results. The `searchTerm` state is managed at the `Pins` container level to enable shared search functionality across components.
This section introduces the comprehensive course, highlighting the creation of three phenomenal applications: a full-stack social media app, a full-stack e-commerce app with payments, and a developer portfolio. The course aims to provide skills for a breakthrough in the web development industry via real-world projects.
The first major project is a modern full-stack social media application called 'ShareMe'. It includes advanced features like Google authentication, image CRUD operations, liking/commenting, and search/filter functionalities. The section begins with setting up the Sanity backend for content management and defining schemas for users, pins, comments, and saves.
Learn how to configure Sanity.io as a unified content platform for 'ShareMe'. This involves installing the Sanity CLI, initializing a new project, logging in with Google, and defining document schemas for 'user', 'pin', 'comment', and 'save'. These schemas structure the data for the social media features.
Detailed creation of Sanity schemas: 'user' with username and image; 'pin' with title, about, destination, category, image (with hotspot), user ID, posted by, saves, and comments; and separate schemas for 'comment' and 'save' to manage user interactions efficiently. This highlights Sanity's intuitive querying language (GROQ).
This part focuses on setting up the React frontend using Create React App and integrating Tailwind CSS for modern UI. It covers the installation of necessary dependencies, including `@sanity/client`, `react-google-login`, `react-router-dom`, and `uuid`. The primary goal is to implement Google OAuth authentication and securely connect it to the Sanity backend.
Detailed steps on integrating Google Login into the React app. This includes obtaining a client ID from Google Cloud Console, storing it as an environment variable, and handling login success to store user data in local storage. The section also covers creating a Sanity client and using `client.createIfNotExists` to persist user profiles in the Sanity database upon successful login.
This segment introduces the development of the main home page for 'ShareMe'. It involves setting up React Router DOM for navigation, creating components like `Sidebar` and `UserProfile`, and organizing components using an `index.js` file for cleaner imports. User data is fetched from Sanity on component mount to dynamically display information.
Detailed implementation of the `Sidebar` component, catering to both mobile and desktop views with responsive design. It includes displaying the app logo, dynamic navigation links (Home, categories), and the user's profile link. The sidebar transitions smoothly for mobile with a hamburger menu, leveraging Tailwind CSS for styling and react-router-dom for active link highlighting.
Development of the `Navbar` component, which includes a search input field, a link to the user's profile, and a button to create new pins. Google user image is dynamically displayed, and navigation to search or create pin pages is handled using `useNavigate` from react-router-dom. Tailwind CSS is used for responsive styling.
This part focuses on the `Feed` component, responsible for fetching and displaying pins from Sanity. It introduces the use of `useParams` for category-specific filtering and the `react-masonry-css` package for creating a responsive, Pinterest-like grid layout. Sanity's GROQ querying language is extensively used to fetch both general and categorized pins efficiently.
The `Feed` component fetches pins based on category IDs. Detailed GROQ queries are created for searching pins by title, category, and description. The section explains how to manually create a sample pin in Sanity Studio to test data fetching and display, emphasizing the dynamic nature of content management.
Developing the individual `Pin` component. This includes displaying the pin's image and enabling interactive elements on hover: download, save, and delete options, along with a link to the original source and the creator's profile. Unique IDs are generated using `uuid`, and complex logic for saving/deleting pins is handled through Sanity client operations.
Detailed explanation and implementation of saving and deleting pins, including handling event propagation. The `alreadySaved` status is determined efficiently using array `filter` and type coercion to a boolean. Sanity's `client.patch` and `client.delete` methods are used to update the database, instantly reflecting changes on the frontend.
A reusable `fetchUser` utility function is created in `utils/data.js` to abstract the logic of retrieving user data from local storage. This promotes code reusability and maintainability across components that need user information without directly accessing local storage repeatedly.
This section guides through building the `CreatePin` component, allowing users to upload new pins. It involves handling multiple state variables for title, about, destination, image asset, and category. The component includes an image upload area with validation for file types and a form for pin details. All dynamic values are linked to Sanity schema fields.
Implementation of image upload functionality within the `CreatePin` component using `client.assets.upload` to store images in Sanity. The `savePin` function collects all form data, constructs a Sanity document, and uses `client.create` to publish the new pin. Error handling and form validation are also covered, including handling timeouts for error messages.
Construction of the `PinDetail` component, which displays comprehensive information about a selected pin. It fetches the main pin details and related pins from Sanity. Features include displaying the pin's image, title, description, creator, and dynamic related pins. The page also provides functionality for users to add comments and view existing comments.
Implementation of `addComment` functionality using `client.patch` to append new comments to a pin's document in Sanity. This section also outlines how to fetch and display related pins (sharing the same category) using specific Sanity queries, enhancing user engagement by suggesting similar content.
Development of the `UserProfile` component, designed to display pins created by or saved by a specific user. It uses `useParams` to identify the user and fetches relevant pins from Sanity. The page features toggleable sections for 'Created' and 'Saved' pins, dynamically changing the displayed content. Google Logout functionality is also integrated.
The `UserProfile` component dynamically displays a random banner image. It integrates the Google Logout button (from `react-google-login`) which clears local storage and navigates the user back to the login page. The core functionality involves fetching and displaying user-specific pins based on whether they were created or saved by the user.
This part focuses on replacing static demo categories with dynamic categories fetched from Sanity in the `Sidebar` component. It ensures that clicking on categories filters pins accordingly and displays appropriate 'No pins available' messages. The final touches also verify the mobile responsiveness and overall functionality of the social media application.
Construction of the `Search` component, which allows users to find pins based on keywords. It utilizes `searchTerm` passed from `Navbar` to query Sanity for relevant pins. The search results are displayed using the `MasonryLayout` component. The component is designed to show a loading spinner during searches and a 'No pins found' message when no results match.
This section covers deploying the 'ShareMe' social media application to Netlify. It includes adding a `_redirects` file for multi-page website routing, building the React application, and dragging the build folder to Netlify. Crucially, it involves updating Sanity CORS origins and Google Cloud Console authorized origins to allow the deployed application to interact with Sanity and Google services.
This begins the second project: a full-stack e-commerce application. It showcases the homepage with a dynamic banner, product listings, and a sale banner. The highlight is Sanity's ability to dynamically modify all content. The setup involves initializing a Next.js project and installing necessary dependencies like Sanity, Stripe, and React Hot Toast.
Detailed guide on setting up Sanity.io for the e-commerce app. Includes installing the Sanity CLI, logging in, creating a new 'clean' project in Sanity Studio, and defining custom schemas for 'product' and 'banner'. The 'product' schema covers images, name, slug, price, and details. The 'banner' schema (provided via GitHub Gist) manages homepage banner content.
Setting up the basic Next.js frontend structure. This involves clearing default Next.js boilerplate, creating components (HeroBanner, Product, Footer), and importing global CSS styles (provided via GitHub Gist) to achieve the base design. The goal is to establish a clean and modular project layout for further development.
This section explains how to link the Next.js application to the Sanity backend to fetch dynamic product and banner data. A `client.js` file is created to initialize the Sanity client with project ID, dataset, API version, and a securely stored token (using `.env` variables). Next.js's `getServerSideProps` is introduced for server-side data fetching to pre-render pages with fresh data.
Implementing the display of dynamic content fetched from Sanity on the e-commerce homepage. This includes rendering the `HeroBanner` component with data from Sanity's 'banner' schema and looping through fetched 'product' data to display individual `Product` components. The process highlights how easy it is to manage and update website content directly from Sanity Studio.
Demonstrates adding multiple products to Sanity Studio, showcasing how the slug is automatically generated and how easy it is to manage product details. Once added, the Next.js application automatically reflects these new products on the homepage, illustrating the power of the Sanity integration.
Development of the `Navbar` and `Footer` components. The `Navbar` includes store branding and a cart icon with a dynamic item quantity (initially static). The `Footer` displays copyright information and social media icons. These components are integrated into the `Layout` component, utilizing the children prop to wrap all main page content, ensuring consistent structural elements across the application.
This section focuses on creating dynamic product detail pages in Next.js using file-based routing with `[slug].js`. It introduces `getStaticProps` for efficient build-time data fetching and `getStaticPaths` to pre-render all possible product routes, ensuring fast page load times and optimal SEO. The component displays product images, name, details, and price.
Integrating a product image gallery functionality, allowing users to hover over thumbnails to view different product angles on a larger display. Also implements interactive quantity adjusters (+/- buttons for increasing/decreasing product quantity) using React Context for global state management. This prepares the groundwork for advanced cart functionalities.
This pivotal section introduces React Context for managing the global state of the e-commerce application, specifically the shopping cart. A `StateContext.js` file is created to hold `showCart`, `cartItems`, `totalPrice`, `totalQuantities`, and `qty` states. Functions for increasing/decreasing quantity (`incQty`, `decQty`) are defined within the context, allowing components across the app to access and modify cart data.
Detailed implementation of the `onAdd` function within the `StateContext`. This function handles adding products to the cart: it checks if an item already exists in the cart to update its quantity, or adds it as a new item. It also updates `totalPrice` and `totalQuantities`. `react-hot-toast` is integrated to provide user-friendly notifications confirming successful item additions.
Development of the `Cart` component, which is toggled by the navbar cart icon. It displays added products with their images, names, and prices. The cart also shows a 'Your shopping bag is empty' message when applicable. The component fetches cart data from `StateContext` and dynamically updates the display.
Refinement of cart functionality with advanced `toggleCartItemQuantity` and `onRemove` functions directly within `StateContext`. This segment addresses common React pitfalls like direct state mutation by demonstrating correct state updates using non-mutative array methods. It enables users to adjust quantities of individual items in the cart and remove items entirely, with real-time updates to the total price and quantities.
This critical section initiates Stripe payment integration. A new `stripe.js` API route is created in Next.js, serving as the backend endpoint for processing payments. Stripe API keys are securely stored in `.env` variables. The focus is on creating a Stripe Checkout Session, including dynamic line items based on cart contents and configuring shipping options (e.g., free shipping, fast shipping) directly from the Stripe dashboard.
The frontend implementation for Stripe checkout. The 'Pay with Stripe' button in the cart component triggers an API request to the Next.js backend. This involves fetching the Stripe instance using `lib/getStripe.js` and passing cart items to the backend. The backend constructs the Stripe checkout session, and upon success, the user is redirected to the Stripe-hosted checkout page. Debugging common errors like CORS and API key issues is also covered.
Development of a dedicated `success.js` page that users are redirected to after a successful Stripe payment. This page displays a 'Thank you for your order' message, instructions for checking email for receipts, and a 'Continue Shopping' button. Critically, it uses a `useEffect` hook to clear the shopping cart's state and local storage, and features a celebratory confetti animation using the `canvas-confetti` library.
Concluding improvements for the e-commerce app: fixing redirection issues after Stripe payment and implementing the 'Buy Now' button. The 'Buy Now' button directly adds the current product to the cart and immediately opens the cart for checkout, streamlining the purchase process. This ensures the application is fully functional and ready for deployment.
Instructions for deploying the Next.js e-commerce application to Vercel. This includes pushing the project to GitHub, importing the repository into Vercel, and configuring environment variables (Sanity token, Stripe keys) within the Vercel project settings. The section demonstrates testing the deployed application with a test payment to ensure all functionalities work live.
Deployment of the Sanity Studio Desk (backend content management interface) online. This allows dynamic content updates for the e-commerce store (adding new products, changing prices, editing banner details) directly via a web interface, without needing developer intervention. The ease of updating content via Sanity is highlighted as a key benefit for store owners.
This section introduces the third project: building a dynamic and customizable developer portfolio. The goal is to create a portfolio that stands out, showcasing skills to employers and clients. The unique aspect is content modification through a modern headless CMS (Sanity), allowing updates without code changes.
Setting up the Sanity backend for the portfolio. This involves creating a new Sanity project within the `backend_sanity` folder, logging in, defining project name, and choosing a clean schema. The process mirrors previous Sanity setups, emphasizing quick and efficient backend creation for dynamic content.
Detailed creation of Sanity schemas for various portfolio sections: 'testimonials' (name, company, image URL, feedback), 'about' (title, description, image URL), 'works' (title, description, project link, code link, image URL, tags), 'skills' (name, icon, background color), 'experiences' (year, works), and 'brands' (name, image URL). This modular approach allows for flexible content management.
Setting up the React frontend using Create React App. This includes deleting default boilerplate, creating a new `src` folder with `index.js` and `App.js`, and installing core dependencies: `@sanity/client`, `@sanity/image-url`, `framer-motion`, `node-sass`, and `react-icons`. The basic app structure and global CSS styles are initialized.
Establishing a clean file and folder structure. Components are categorized into `components` (smaller, reusable items) and `containers` (larger sections with multiple components). An `index.js` file in each folder (components, containers, constants, wrapper) centralizes exports for cleaner imports, improving code readability and maintainability.
Construction and styling of the `Navbar` component. This includes the logo and navigation links using a BEM (Block, Element, Modifier) methodology for CSS. The navigation is responsive, transitioning to a hamburger menu with a blurred background effect on smaller screens. `framer-motion` is introduced for smooth animations when opening/closing the mobile menu.
Development of the `Header` (hero) section, featuring a personal introduction. `framer-motion` is extensively used for animations: the main text animates from the left, a profile image animates in, and skill icons (e.g., React, Redux) float in an animated circle pattern. This combines visual appeal with a strong first impression for the portfolio.
Building the 'About' section, designed to showcase personal skills and expertise. The section uses dynamic data fetched from Sanity CMS, allowing easy updates to titles, descriptions, and images for different skill categories (e.g., web development, UI/UX). `framer-motion` is applied for subtle hover effects on each skill card.
This crucial step details how to integrate the React application with the Sanity CMS. A `client.js` file is created to configure the Sanity client using securely stored API keys and project IDs. It also sets up an `imageUrlBuilder` utility for optimizing image fetching from Sanity. This enables dynamic content population from the CMS into React components.
Demonstrates fetching 'about' data from Sanity using `client.fetch` within a `useEffect` hook. The fetched data dynamically populates the 'About' section, replacing static content. Michael Michael (the persona) then adds multiple 'about' items (skills) in Sanity Studio, illustrating how content changes reflect immediately on the React frontend, showcasing the power of CMS integration.
This section introduces a powerful React concept: Higher Order Components (HOCs). An `AppWrap` HOC is created to centralize common functionalities like adding social media icons, navigation dots, and consistent styling (e.g., full height, background colors) to multiple sections. This reduces code duplication and streamlines the development of new sections.
Construction of the 'Work' (Portfolio) section. It fetches portfolio project data from Sanity CMS and displays project cards with images, titles, descriptions, and links to live projects or GitHub repositories. Filterable categories (UI/UX, web app, mobile app, React.js, all) are implemented to dynamically reorder projects, with `framer-motion` providing smooth transition animations between categories.
Implementation of filtering functionality for portfolio projects. The `handleWorkFilter` function updates the `activeFilter` and triggers `framer-motion` animations, making project cards animate out and then back in based on the selected category. This provides an interactive and visually appealing experience for showcasing different types of projects.
Development of the 'Skills & Experience' section. It fetches technical skills (e.g., React, Node.js) and work experiences from Sanity. Skills are displayed as animated circular icons, and experiences are presented by year with detailed job descriptions and company names. React Tooltip is integrated to show descriptions on hover, enhancing user interaction.
This part focuses on populating the 'Skills' and 'Experience' sections with dynamically fetched data from Sanity. Skills are displayed as circular icons that scale on hover, and work experiences are presented as a timeline, categorized by year. Debugging steps are shown to resolve common issues with data fetching and rendering when integrating dynamic content from a CMS.
Introduction of another HOC, `MotionWrap`, to add scroll-based animations to each section. This HOC wraps individual `AppWrap` components (like 'About', 'Work', 'Skills'), providing consistent animations (e.g., fade-in and slide-up) as users scroll through the portfolio. This enhances the overall user experience by making the page more dynamic and engaging.
Construction of the 'Testimonial' section. It fetches testimonial data (name, company, feedback) and brand logos from Sanity. The component displays one testimonial at a time, allowing users to navigate between them using left/right arrow icons. Brand logos of companies worked with are displayed below the testimonials, dynamically updating from Sanity.
Styling for the 'Testimonial' section. This involves making testimonial cards responsive and visually appealing, with navigation buttons for cycling through testimonials. Brand logos are initially greyed out and gain color on hover, providing an interactive element. Media queries ensure the layout adapts well across various screen sizes.
Instructions on how to deploy the Sanity Studio Desk online. This allows content creators or administrators to manage the application's content (users, pins, comments) without needing direct code access. The deployment ensures that anyone with access to the Sanity Studio can update the application's data dynamically.