Skip to main content

React Laravel 12 Ecommerce App | Product, Cart & Checkout Page UI Design (Part 3)

  Welcome to Part 3 of the React Laravel 12 Ecommerce App Tutorial Series 🛒🚀 In this video, we’ll design the Product Page, Cart Page, and Checkout Page UI for our Ecommerce application using React JS frontend. These pages are essential for creating a complete online store where users can view products, add them to cart, and proceed to checkout. 🔥 What you’ll learn in this video: ✅ Design a Product Page UI with product details layout ✅ Create a Cart Page UI to show added products ✅ Build a Checkout Page UI for order summary & payment flow ✅ Structure pages for future backend API integration (Laravel 12) ✅ Build responsive and clean ecommerce pages using React  Watch the video: 👉 Trash Icon : <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" className="bi bi-trash3" viewBox="0 0 16 16"> <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5M11 2.5v-1A1.5 1.5 0 0 0 9.5...

🚀 React + Laravel Blog App Tutorial (Step by Step Playlist)

Welcome to my React + Laravel Blog App tutorial series. In this playlist, we will build a complete Blog application using Laravel 12 (as backend API) and React JS (as frontend).


👉 You can follow along with the videos on my YouTube Playlist here:

React + Laravel Blog App Playlist on YouTube


Welcome to the React Laravel 12 Blog App Tutorial Series 🚀 In this step-by-step full stack tutorial, we’ll build a complete Blog Application using React JS (frontend) and Laravel 12 (backend REST APIs). This series is designed for beginners as well as developers who want to master full stack development with React and Laravel by building a real-world project. 🔥 What you’ll learn in this playlist:

1️⃣ React Laravel 12 Blog App Setup | Frontend & Backend Project + Blog UI Design Tutorial
1️⃣ React Laravel 12 Blog App | Create Blog API + React Integration with Toast & Editor (Part 2)
1️⃣ React Laravel 12 Blog App | Upload Image (Backend + Frontend Integration) Tutorial (Part 3)
1️⃣ React Laravel 12 Blog App | Fetch Blogs API & Display in React Frontend (Part 4)
1️⃣ React Laravel 12 Blog App | Blog Detail Page with API Integration (Part 5)
1️⃣ React Laravel 12 Blog App | Edit Blog with API Integration (Part 6)
1️⃣ React Laravel 12 Blog App | Delete Blog with API Integration (Part 7)
1️⃣ React Laravel 12 Blog App | Search Blogs with API Integration (Part 8)

By the end of this playlist, you’ll have a fully functional React + Laravel 12 Blog Application built completely from scratch. 👉 Make sure to subscribe and follow along with each part of this playlist to build the project step by step. React Laravel 12 Blog App, Full Stack Blog App with React and Laravel, Laravel 12 Blog Project, React Blog App Tutorial, Laravel React Full Stack Development, Blog App CRUD with React Laravel, React JS Laravel 12 REST API, Full Stack Web Development Tutorial, Build Blog App with React and Laravel 12, React Laravel Blog Series


📂 Playlist Overview

1️⃣ React Laravel 12 Blog App Setup | Frontend & Backend Project + Blog UI Design Tutorial
1️⃣ React Laravel 12 Blog App | Create Blog API + React Integration with Toast & Editor (Part 2)
1️⃣ React Laravel 12 Blog App | Upload Image (Backend + Frontend Integration) Tutorial (Part 3)
1️⃣ React Laravel 12 Blog App | Fetch Blogs API & Display in React Frontend (Part 4)
1️⃣ React Laravel 12 Blog App | Blog Detail Page with API Integration (Part 5)
1️⃣ React Laravel 12 Blog App | Edit Blog with API Integration (Part 6)
1️⃣ React Laravel 12 Blog App | Delete Blog with API Integration (Part 7)
1️⃣ React Laravel 12 Blog App | Search Blogs with API Integration (Part 8)


📂 React Js App Source Code

📜 React App (main.jsx):

import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'

import App from './App.jsx'
import { BrowserRouter } from 'react-router-dom'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <BrowserRouter>
    <App />
    </BrowserRouter>
  </StrictMode>,
)




📜 React App (App.jsx):

import { useState } from 'react'
import 'bootstrap/dist/css/bootstrap.min.css';
import BlogCard from './components/BlogCard';
import { Route, Routes } from 'react-router-dom';
import { Blogs } from './components/Blogs';
import { Contact } from './components/Contact';
import { CreateBlog } from './components/CreateBlog';

import { ToastContainer, toast } from 'react-toastify';
import BlogDetail from './components/BlogDetail';
import EditBlog from './components/EditBlog';

function App() {
  return (
    <>

     <div className='bg-dark text-center py-2 shadow-lg'>
        <h1 className='text-white'>React & Laravel Blog App</h1>
      </div>

    <Routes>
      <Route path='/' element={<Blogs/>} />
      <Route path='/create' element={<CreateBlog/>} />
      <Route path='/blog/:id' element={<BlogDetail/>} />
      <Route path='/blog/edit/:id' element={<EditBlog/>} />
    </Routes>

     <ToastContainer />

     
    </>
  )
}

export default App



📜 React App (BlogCard.jsx):

import { toast } from "react-toastify";

const BlogCard = ({blog, blogs, setBlogs}) => {

  const showImage = (img) => {
    return (img) ? 'http://127.0.0.1:8000/uploads/blogs/' + img : 'https://placehold.co/600x400';
  }

  const deleteBlog = (id) => {
    if(confirm("Are you sure to delete this blog?")) {
      const res = fetch('http://127.0.0.1:8000/api/blogs/' + id, {
        method: 'DELETE'
      });

      const newBlogs = blogs.filter( (blog) => blog.id !== id );
      setBlogs(newBlogs);
      toast("Blog Deleted Successfully!" );
    }
  }

    return (
        <>
        <div className='col-12 col-md-2 col-lg-3 mb-4'>
            <div className='card border-0 shadow-lg'>
              <img src={showImage(blog.image)} className='card-img-top' alt='...' />
              <div className='card-body'>
                <h2 className='h5'>{blog.title}</h2>
                <p>{blog.shortDesc}</p>
                <div className='d-flex justify-content-between'>
                  <a href={`/blog/${blog.id}`} className='btn btn-dark'>Details</a>

                  <div>

                    <a href='#' className="text-danger" onClick={() => deleteBlog(blog.id)}>
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-trash" viewBox="0 0 16 16">
                      <path d="M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z"/>
                      <path d="M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z"/>
                    </svg>
                  </a>
                  <a href={`/blog/edit/${blog.id}`} className='text-dark ms-2'>
                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" className="bi bi-pencil" viewBox="0 0 16 16">
                      <path d="M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325"/>
                    </svg>
                  </a>
                 
                  </div>

                 
                </div>
              </div>
            </div>
            </div>
        </>
    );
}

export default BlogCard;

📜 React App (BlogDetail.jsx):


import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom';

const BlogDetail = () => {

    const [blog, setBlog] = useState([]);
    const params = useParams();

    const fetchBlog = async () => {
        // getting blog id from url
        const res = await fetch('http://127.0.0.1:8000/api/blogs/' + params.id);
        const result = await res.json();
        setBlog(result.data);
    }

    useEffect(() => {
        fetchBlog();
    }, []);

  return (
     <div className='container'>
        <div className='d-flex justify-content-between pt-5 mb-4'>
          <h2>{blog.title}</h2>
          <div>
            <a href='/' className='btn btn-dark'>Back to blogs</a>
          </div>
         
        </div>


        <div className='row'>

          <div className='col-md-12'>
            <p>by <strong>{blog.author}</strong> on {blog.date}</p>


            {
                (blog.image) && <img className='w-100' src={`http://127.0.0.1:8000/uploads/blogs/${blog.image}`}/>
            }

            <div dangerouslySetInnerHTML={{__html: blog.description}} className='mt-4'>
       
            </div>

          </div>
         
        </div>
      </div>
  )
}

export default BlogDetail

📜 React App (Blogs.jsx):


import React, { useEffect, useState } from 'react'
import BlogCard from './BlogCard'

export const Blogs = () => {
  const [Blogs, setBlogs] = useState();
  const [keyword, setKeyword] = useState('');

  const fetchBlogs = async () => {
    const res = await fetch('http://127.0.0.1:8000/api/blogs');
    const result = await res.json();
    setBlogs(result.data);
  }

  const searchBlogs = async (e) => {
    e.preventDefault();
    const res = await fetch('http://127.0.0.1:8000/api/blogs?keyword=' + keyword);
    const result = await res.json();
    setBlogs(result.data);
  }

  const resetSearch = () => {
    fetchBlogs();
    setKeyword('');
  }

  useEffect(() => {
    fetchBlogs();
  }, []);



  return (
     <div className='container'>



      <div className='d-flex justify-content-center pt-5 mb-4'>

        <form onSubmit={(e) => searchBlogs(e)}>
          <div className='d-flex'>
            <input type='text' value={keyword} onChange={(e) => setKeyword(e.target.value)} className='form-control' placeholder='Search...' />
       
            <button className='btn btn-dark ms-2'>Search</button>
            <button type='button' onClick={() => {resetSearch()}} className='btn btn-success ms-2'>Reset</button>
         </div>

          </form>


        </div>


        <div className='d-flex justify-content-between pt-5 mb-4'>
          <h4>Blog</h4>
          <a href='/create' className='btn btn-dark'>Create</a>
        </div>


        <div className='row'>

          { (Blogs) && Blogs.map( (blog) => {
            return ( <BlogCard blogs={Blogs} setBlogs={setBlogs} key={blog.id} blog={blog}/> )
            })
          }
         
         
         
        </div>


      </div>
  )
}




📜 React App (CreateBlog.jsx)

import React, { useState } from 'react'
import Editor from 'react-simple-wysiwyg';
import { useForm } from "react-hook-form"
import { toast } from 'react-toastify';
import { useNavigate } from 'react-router-dom';

export const CreateBlog = () => {
     const [html, setHtml] = useState('');
      const [imageId, setImageId] = useState(null);


     const navigate = useNavigate();

     function onChange(e) {
        setHtml(e.target.value);
    }

    const handleFileChange = async (e) => {
      const file = e.target.files[0];
      const formData = new FormData();
      formData.append('image', file);

      const res = await fetch("http://127.0.0.1:8000/api/save-temp-image", {
        method: 'POST',
        body: formData
      });

      const result = await res.json();
       if(result.status == false){
         alert(result.errors.image);
         e.target.value = null;
       }

       setImageId(result.image.id);
    }

     const {
        register,
        handleSubmit,
        watch,
        formState: { errors },
      } = useForm();

      const formSubmit = async (data) => {
        const newData = {...data, "description": html, "image_id": imageId};
        //call api
        const res = await fetch('http://127.0.0.1:8000/api/blogs', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify(newData),
        })

        toast("BLog Created Successfully");
        //navigate to home page
        navigate('/');
      }

  return (
    <div className='container mb-5'>
       <div className='d-flex justify-content-between pt-5 mb-4'>
          <h4>Create Blog</h4>
          <a href='/' className='btn btn-dark'>Back</a>
        </div>

        <div className='card border-0 shadow-lg'>
          <form onSubmit={handleSubmit(formSubmit)}>
            <div className='card-body'>
                 <div className='mb-3'>
                    <label htmlFor='' className='form-label'>Title</label>
                    <input
                    {...register("title", { required: true })}
                     type='text'
                     className={`form-control ${errors.title ? 'is-invalid' : ''}`}
                      placeholder='Title'/>

                     {errors.title && <p className='invalid-feedback'>Title field is required</p>}
                </div>
                 <div className='mb-3'>
                    <label htmlFor='' className='form-label'>SHort Description</label>
                    <textarea
                    {...register("shortDesc", { required: true })}
                     className='form-control' rows={5} cols={30} placeholder='Short Description'></textarea>
                </div>
                 <div className='mb-3'>
                    <label htmlFor='' className='form-label'>Description</label>
                    {/* <textarea className='form-control' rows={4} placeholder='Description'></textarea> */}
                     <Editor
                     containerProps={{ style: { height: '400px' } }}
                      value={html} onChange={onChange} />
                </div>
                <div className='mb-3'>
                    <label htmlFor='' className='form-label'>Image</label>
                    <input onChange={handleFileChange} type='file' className='form-control' />
                </div>
                 <div className='mb-3'>
                    <label htmlFor='' className='form-label'>Author</label>
                    <input {...register("author", { required: true })} type='text' className={`form-control ${errors.author ? 'is-invalid' : ''}`} placeholder='Author'/>
                    {errors.author && <p className='invalid-feedback'>Author field is required</p>}
                </div>
               
                    <button className='btn btn-dark'>Submit</button>

            </div>
            </form>
           
        </div>
    </div>
  )
}


📜 React App (EditBlog.jsx):

import React, { useEffect, useState } from 'react'
import Editor from 'react-simple-wysiwyg';
import { useForm } from "react-hook-form"
import { toast } from 'react-toastify';
import { useNavigate, useParams } from 'react-router-dom';

const EditBlog = () => {

    const [html, setHtml] = useState('');
    const [imageId, setImageId] = useState(null);
    const [blog, setBlog] = useState([]);
    const params = useParams();


    const navigate = useNavigate();

    function onChange(e) {
        setHtml(e.target.value);
    }

    const handleFileChange = async (e) => {
        const file = e.target.files[0];
        const formData = new FormData();
        formData.append('image', file);

        const res = await fetch("http://127.0.0.1:8000/api/save-temp-image", {
            method: 'POST',
            body: formData
        });

        const result = await res.json();
        if (result.status == false) {
            alert(result.errors.image);
            e.target.value = null;
        }

        setImageId(result.image.id);
    }

    const {
        register,
        handleSubmit,
        watch,
        reset,
        formState: { errors },
    } = useForm();

    const fetchBlog = async () => {
        // getting blog id from url
        const res = await fetch('http://127.0.0.1:8000/api/blogs/' + params.id);
        const result = await res.json();
        setBlog(result.data);
        setHtml(result.data.description);
        reset(result.data);
    }

    useEffect(() => {
        fetchBlog();
    }, []);

    const formSubmit = async (data) => {
            const newData = {...data, "description": html, "image_id": imageId};
            //call api
            const res = await fetch('http://127.0.0.1:8000/api/blogs/' + params.id, {
              method: 'PUT',
              headers: {
                'Content-Type': 'application/json',
              },
              body: JSON.stringify(newData),
            })
   
            toast("BLog Updated Successfully");
            //navigate to home page
            navigate('/');
          }
   

    return (
       <div className='container mb-5'>
              <div className='d-flex justify-content-between pt-5 mb-4'>
                 <h4>Edit Blog</h4>
                 <a href='/' className='btn btn-dark'>Back</a>
               </div>
       
               <div className='card border-0 shadow-lg'>
                 <form onSubmit={handleSubmit(formSubmit)}>
                   <div className='card-body'>
                        <div className='mb-3'>
                           <label htmlFor='' className='form-label'>Title</label>
                           <input
                           {...register("title", { required: true })}
                            type='text'
                            className={`form-control ${errors.title ? 'is-invalid' : ''}`}
                             placeholder='Title'/>
       
                            {errors.title && <p className='invalid-feedback'>Title field is required</p>}
                       </div>
                        <div className='mb-3'>
                           <label htmlFor='' className='form-label'>SHort Description</label>
                           <textarea
                           {...register("shortDesc", { required: true })}
                            className='form-control' rows={5} cols={30} placeholder='Short Description'></textarea>
                       </div>
                        <div className='mb-3'>
                           <label htmlFor='' className='form-label'>Description</label>
                           {/* <textarea className='form-control' rows={4} placeholder='Description'></textarea> */}
                            <Editor
                            containerProps={{ style: { height: '400px' } }}
                             value={html} onChange={onChange} />
                       </div>
                       <div className='mb-3'>
                           <label htmlFor='' className='form-label'>Image</label>
                           <input onChange={handleFileChange} type='file' className='form-control' />

                            <div className='mt-3'>
                           {
                                (blog.image) && <img className='w-100' src={`http://127.0.0.1:8000/uploads/blogs/${blog.image}`}/>
                            }
                            </div>
                       </div>
                        <div className='mb-3'>
                           <label htmlFor='' className='form-label'>Author</label>
                           <input {...register("author", { required: true })} type='text' className={`form-control ${errors.author ? 'is-invalid' : ''}`} placeholder='Author'/>
                           {errors.author && <p className='invalid-feedback'>Author field is required</p>}
                       </div>
                     
                           <button className='btn btn-dark'>Update</button>
       
                   </div>
                   </form>
                 
               </div>
           </div>
    )
}

export default EditBlog


📂 Laravel App Source Code

📜 Laravel App (BlogController.php)

<?php

namespace App\Http\Controllers;

use App\Models\Blog;
use App\Models\TempImage;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Validator;

class BlogController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {

        $blogs = Blog::orderBy('created_at', 'DESC');
        if(!empty($request->keyword)){
            $blogs = $blogs->where('title', 'LIKE', '%'.$request->keyword.'%');
        }

        $blogs = $blogs->get();
        return response()->json([
            'status' => true,
            'data' => $blogs
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //validation
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|min:10|max:255',
            'shortDesc' => 'nullable|string|max:500',
            'image' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048',
            'description' => 'nullable|string',
            'author' => 'required|string|min:3|max:255',
        ]);

        if($validator->fails()){
            return response()->json([
                'status' => false,
                'errors' => $validator->errors(),
                'message' => 'Validation error'
            ]);
        }

        //insert blog in database
        $blog = new Blog();
        $blog->title = $request->title;
        $blog->shortDesc = $request->shortDesc;
        $blog->description = $request->description;
        $blog->author = $request->author;
        $blog->save();

        //save image
        $tempImage = TempImage::find($request->image_id);
        if($tempImage != null ){
            $imageExtArray = explode('.', $tempImage->name);
            $ext = last($imageExtArray);  // we are getting the extension of the image
            $imageName = time(). '-' . $blog->id .'.'. $ext; // we are renaming the image with blog id

            $blog->image = $imageName;
            $blog->save();

            //move image from temp folder to blogs folder
            $sourcePath = public_path('uploads/temp/'.$tempImage->name);
            $destinationPath = public_path('uploads/blogs/'.$imageName);

            File::copy($sourcePath, $destinationPath); //copy image from temp to blogs folder
            File::delete($sourcePath); // delete image from temp folder
        }


         return response()->json([
                'status' => true,
                'message' => 'Blog Added Successfully',
                'data' => $blog
            ]);
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        $blog = Blog::find($id);
        if($blog == null){
            return response()->json([
                'status' => false,
                'message' => 'Blog not found'
            ]);
        }

        $blog['date'] = Carbon::parse($blog->created_at)->format('d M, Y');

        return response()->json([
                'status' => true,
                'data' => $blog
            ]);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {

        $blog = Blog::find($id);

        if($blog == null){
             return response()->json([
                'status' => false,
                'message' => 'Blog not found'
            ]);
        }
        //validation
        $validator = Validator::make($request->all(), [
            'title' => 'required|string|min:10|max:255',
            'shortDesc' => 'nullable|string|max:500',
            'description' => 'nullable|string',
            'author' => 'required|string|min:3|max:255',
        ]);

        if($validator->fails()){
            return response()->json([
                'status' => false,
                'errors' => $validator->errors(),
                'message' => 'Validation error'
            ]);
        }

        //update blog in database

        $blog->title = $request->title;
        $blog->shortDesc = $request->shortDesc;
        $blog->description = $request->description;
        $blog->author = $request->author;
        $blog->save();

        //save image
        $tempImage = TempImage::find($request->image_id);
        if($tempImage != null ){

            File::delete(public_path('uploads/blogs/'.$blog->image)); // delete old image from blogs folder if exists

            $imageExtArray = explode('.', $tempImage->name);
            $ext = last($imageExtArray);  // we are getting the extension of the image
            $imageName = time(). '-' . $blog->id .'.'. $ext; // we are renaming the image with blog id

            $blog->image = $imageName;
            $blog->save();

            //move image from temp folder to blogs folder
            $sourcePath = public_path('uploads/temp/'.$tempImage->name);
            $destinationPath = public_path('uploads/blogs/'.$imageName);

            File::copy($sourcePath, $destinationPath); //copy image from temp to blogs folder
            File::delete($sourcePath); // delete image from temp folder
        }


         return response()->json([
                'status' => true,
                'message' => 'Blog Updated Successfully',
                'data' => $blog
            ]);
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        $blog = Blog::find($id);

        if($blog == null){
             return response()->json([
                'status' => false,
                'message' => 'Blog not found'
            ]);
        }

        //delete blog image first if exists
        File::delete(public_path('uploads/blogs/'.$blog->image));

        //delete blog from db
        $blog->delete();


        return response()->json([
                'status' => true,
                'message' => 'Blog Deleted Successfully'
            ]);
    }
}



📜 Laravel App (TempImageController.php)


<?php

namespace App\Http\Controllers;

use App\Models\TempImage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;

class TempImageController extends Controller
{
    public function store (Request $request) {
       // validate the image
       $validator = Validator::make($request->all(), [
         'image' => 'required|image',
       ]);

       if($validator->fails()){
            return response()->json([
                'status' => false,
                'message' => 'Validation error',
                'errors' => $validator->errors()
            ]);
       }

       //upload image
        $image = $request->image;
        $ext = $image->getClientOriginalExtension();
        $imageName = time().'.'.$ext;

        //store image info in database
        $tempImage = new TempImage();
        $tempImage->name = $imageName;
        $tempImage->save();

        //move img in temp directory
        $image->move(public_path('uploads/temp'), $imageName);

        return response()->json([
                'status' => true,
                'message' => 'Image uploaded successfully',
                'image' => $tempImage
            ]);
    }
}


📜 Laravel App (api.php):

<?php

use App\Http\Controllers\BlogController;
use App\Http\Controllers\TempImageController;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

Route::get('/user', function (Request $request) {
    return $request->user();
})->middleware('auth:sanctum');


Route::get('blogs', [BlogController::class, 'index']);
Route::post('blogs', [BlogController::class, 'store']);
Route::post('save-temp-image', [TempImageController::class, 'store']);
Route::get('blogs/{id}', [BlogController::class, 'show']);
Route::put('blogs/{id}', [BlogController::class, 'update']);
Route::delete('blogs/{id}', [BlogController::class, 'destroy']);




🎉 Final Features of Blog App

✔ Create Blog
✔ View All Blogs
✔ Update Blog
✔ Delete Blog
✔ API powered by Laravel 12
✔ Frontend powered by React JS


🔔 Stay Connected

👉 Subscribe to my YouTube Channel for more tutorials.
👉 Follow the full playlist here: React + Laravel Blog App Playlist
👉 Leave a comment if you face any issue — I’ll help you out 🙂


Comments

Popular posts from this blog

React Laravel 12 Ecommerce App | Home & Shop Page UI Design (Part 2)

 Welcome to Part 2 of the React Laravel 12 Ecommerce App Tutorial Series 🛒🚀 In this video, we’ll design the Home Page and Shop Page UI for our Ecommerce application using React JS frontend . This is the first step in building a user-friendly Ecommerce store, where users will be able to browse products easily. 🔥 What you’ll learn in this video: ✅ Design a modern Home page for Ecommerce App ✅ Create a Shop page layout with product grid ✅ Build responsive UI using React components ✅ Setup structure for showing dynamic product data later ✅ Prepare frontend for API integration with Laravel backend  Watch the video: 👉 Google Font: @import url ( 'https://fonts.googleapis.com/css2?family=DM+Sans:ital, opsz,wght@0,9..40,100..1000;1,9..40,100..1000&display=swap' ); 👉 Global Variables: $primary-font : "DM Sans" , sans-serif ; $primary-white : #FFF ; $primary-color : #43c3D1 ; $primary-black : #061123 ; $secondary-color : #0284FF ; $tertiary-color : #2F48...

React Laravel 12 Ecommerce App | Product, Cart & Checkout Page UI Design (Part 3)

  Welcome to Part 3 of the React Laravel 12 Ecommerce App Tutorial Series 🛒🚀 In this video, we’ll design the Product Page, Cart Page, and Checkout Page UI for our Ecommerce application using React JS frontend. These pages are essential for creating a complete online store where users can view products, add them to cart, and proceed to checkout. 🔥 What you’ll learn in this video: ✅ Design a Product Page UI with product details layout ✅ Create a Cart Page UI to show added products ✅ Build a Checkout Page UI for order summary & payment flow ✅ Structure pages for future backend API integration (Laravel 12) ✅ Build responsive and clean ecommerce pages using React  Watch the video: 👉 Trash Icon : <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" className="bi bi-trash3" viewBox="0 0 16 16"> <path d="M6.5 1h3a.5.5 0 0 1 .5.5v1H6v-1a.5.5 0 0 1 .5-.5M11 2.5v-1A1.5 1.5 0 0 0 9.5...

React Laravel 12 Blog App Setup | Frontend & Backend Project + Blog UI Design Tutorial

  Welcome to the React Laravel 12 Blog App Tutorial Series! 🚀 In this first video, we’ll set up the Blog project (frontend + backend) and start designing the Blog UI step by step. This series is perfect if you want to learn full stack development with React and Laravel 12 by building a real-world blog application. 🔥 What you’ll learn in this video: ✅ Setup Laravel 12 backend project for the Blog App ✅ Create React frontend project for the Blog App ✅ Configure project structure for full stack development ✅ Design clean and responsive Blog UI with React ✅ Prepare backend for CRUD APIs (coming in next videos) By the end of this tutorial, you’ll have a fully functional React + Laravel 12 Blog App setup with a professional UI design ready for backend integration. 🎥 Watch the Tutorial 📂 Get the Source Code 👉 I am not sharing the source code here. You can get the full project code (React components + Laravel API code) from my main playlist post: 👉 React + Laravel Blog App ...