<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Seif Eddine Saad</title>
    <description>The latest articles on Forem by Seif Eddine Saad (@seif_eddine_saad).</description>
    <link>https://forem.com/seif_eddine_saad</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1858811%2F7ae83958-f553-4648-bf65-e651bae73893.jpg</url>
      <title>Forem: Seif Eddine Saad</title>
      <link>https://forem.com/seif_eddine_saad</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/seif_eddine_saad"/>
    <language>en</language>
    <item>
      <title>Convert &amp; Optimize Images with Python &amp; Pillow 🚀</title>
      <dc:creator>Seif Eddine Saad</dc:creator>
      <pubDate>Mon, 28 Apr 2025 07:58:22 +0000</pubDate>
      <link>https://forem.com/seif_eddine_saad/convert-optimize-images-with-python-pillow-4i61</link>
      <guid>https://forem.com/seif_eddine_saad/convert-optimize-images-with-python-pillow-4i61</guid>
      <description>&lt;p&gt;Working with lots of images? Whether you’re handling user-uploads, prepping assets for the web, or just cleaning up a folder of photos, automating conversion and compression will save you hours of manual work—and bandwidth!&lt;/p&gt;

&lt;p&gt;In this tutorial you’ll learn how to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Batch-convert any image (PNG, WEBP, TIFF, BMP…) to JPEG&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optimize the resulting JPEGs for web-friendly file sizes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Package it all into a one-file Python script&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  🛠️ Prerequisites:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Python 3.6+ installed on your machine&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Basic comfort with the command line&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;(Optional) A virtualenv or Conda environment&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pip install pillow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  📂 Project Structure:
&lt;/h2&gt;

&lt;p&gt;Create a folder called image-converter with two subfolders:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;image-converter/
├─ input_images/    ← put your source files here
└─ output_images/   ← optimized JPGs will land here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔥 The Script:
&lt;/h2&gt;

&lt;p&gt;Create convert_images.py in image-converter/ and paste:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from PIL import Image
import os
import sys

# 1️⃣ Determine script’s own directory
BASE_DIR = os.path.dirname(os.path.abspath(__file__))

# 2️⃣ Define input/output folders
input_folder  = os.path.join(BASE_DIR, 'input_images')
output_folder = os.path.join(BASE_DIR, 'output_images')

# 3️⃣ Sanity checks
if not os.path.isdir(input_folder):
    print(f"❌ Input folder not found: {input_folder}")
    sys.exit(1)
os.makedirs(output_folder, exist_ok=True)

# 4️⃣ Gather images
valid_exts = ('png', 'webp', 'jpeg', 'jpg', 'tiff', 'bmp')
files = [f for f in os.listdir(input_folder)
         if f.lower().endswith(valid_exts)]

if not files:
    print("❌ No images found in", input_folder)
    sys.exit(1)

print(f"🔍 Found {len(files)} image(s):")
for f in files: print("  •", f)

# 5️⃣ Conversion loop
for fname in files:
    src_path = os.path.join(input_folder, fname)
    img = Image.open(src_path).convert('RGB')   # ensure JPEG-compatible

    base, _ = os.path.splitext(fname)
    dst_path = os.path.join(output_folder, f"{base}.jpg")

    # quality=85 is usually a sweet spot; optimize=True shrinks a bit more
    img.save(dst_path, "JPEG", quality=85, optimize=True)
    print(f"✅ Saved: {dst_path}")

print(f"\n🎉 Done! Converted &amp;amp; optimized {len(files)} files.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 How It Works&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Absolute paths&lt;br&gt;
We compute BASE_DIR so you can run the script from anywhere, and it will always locate the right folders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;File filtering&lt;br&gt;
We only pick files with common image extensions—even skips over stray text files or hidden folders.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RGB conversion&lt;br&gt;
JPEG doesn’t support alpha/transparency. Converting to RGB ensures no errors.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Quality &amp;amp; optimization&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;quality=85 retains visual fidelity with ~30–50% smaller size than 100.&lt;/li&gt;
&lt;li&gt;optimize=True applies an extra compression pass.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ✅ Running It
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Drop all your images into input_images/.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From the terminal (inside image-converter/):&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;python convert_images.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope this saves you time and bandwidth. If you 💚 it, give it a clap, and drop any questions or improvements below!&lt;/p&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>webdev</category>
      <category>learning</category>
    </item>
    <item>
      <title>Next JS &amp; Supabase CRUD🚀</title>
      <dc:creator>Seif Eddine Saad</dc:creator>
      <pubDate>Sun, 01 Sep 2024 14:37:28 +0000</pubDate>
      <link>https://forem.com/seif_eddine_saad/next-js-supabase-crud-1jk5</link>
      <guid>https://forem.com/seif_eddine_saad/next-js-supabase-crud-1jk5</guid>
      <description>&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;Creating a CRUD (Create, Read, Update, Delete) application is a core skill for web developers, and using Next.js with Supabase makes it even easier. In this guide, we'll explore how to build a fully functional CRUD app using Next.js for the frontend and Supabase for the backend.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://next-supabase-crud-eight.vercel.app" rel="noopener noreferrer"&gt;https://next-supabase-crud-eight.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Github:
&lt;/h2&gt;

&lt;p&gt;Give it a star⭐️&lt;br&gt;
&lt;a href="https://github.com/seifeddinesaad01/Next-Supabase-CRUD" rel="noopener noreferrer"&gt;https://github.com/seifeddinesaad01/Next-Supabase-CRUD&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Requirement:
&lt;/h2&gt;

&lt;p&gt;Before we go so far, let’s prepare some software we need.&lt;/p&gt;
&lt;h4&gt;
  
  
  Software
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;npm: (&lt;a href="https://www.npmjs.com" rel="noopener noreferrer"&gt;https://www.npmjs.com&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Visual Studio Code: (&lt;a href="https://code.visualstudio.com" rel="noopener noreferrer"&gt;https://code.visualstudio.com&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Account
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Supabase Account (&lt;a href="https://supabase.com" rel="noopener noreferrer"&gt;https://supabase.com&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  1.Setup Project:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ npm create next-app next14-supabase-crud
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  2.Install Dependencies:
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ yarn add @supabase/supabase-js

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  3. Supabase:
&lt;/h2&gt;

&lt;p&gt;Create supabase project, fill the form&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pele53fu3blsb8d6f2m.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3pele53fu3blsb8d6f2m.PNG" alt="Image description" width="800" height="364"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then it will redirect into your project detail&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsovaolmoizi2erqdcgyb.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsovaolmoizi2erqdcgyb.PNG" alt="Image description" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  4.Configure Environment Variable:
&lt;/h2&gt;

&lt;p&gt;Let’s create .env file, and copy-paste this code below and define variable value based on supabase config.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_SUPABASE_URL=supabase-url
NEXT_PUBLIC_SUPABASE_KEY=supabase-key

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. Supabase configuration:
&lt;/h2&gt;

&lt;p&gt;Then create supabase configuration file ./config/supabase.js, and copy paste code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createClient } from '@supabase/supabase-js';

const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_KEY;
const supabase = createClient(supabaseUrl, supabaseKey);
export default supabase;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Create Table Posts:
&lt;/h2&gt;

&lt;p&gt;Create table named posts and define table column.Don’t forget to uncheck Enable Row Level Security (RLS) to make read and write access public.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frptix3a1i7uvjldz3503.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frptix3a1i7uvjldz3503.PNG" alt="Image description" width="596" height="636"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84yijysnr3gdgnoh8hh8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84yijysnr3gdgnoh8hh8.PNG" alt="Image description" width="594" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Folder structure :
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ezg2ldgsz8dfs2ttrun.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6ezg2ldgsz8dfs2ttrun.PNG" alt="Image description" width="335" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Create Page to List All Posts
&lt;/h2&gt;

&lt;p&gt;Update page app/page.tsx and copy paste code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client"
import supabase from "../config/supabase";
import Head from "next/head";
import Link from "next/link";
import { useEffect, useState } from "react";
import { CiEdit } from "react-icons/ci";
import { MdDeleteOutline } from "react-icons/md";
import { Empty } from 'antd';



export default function Home() {
  const [posts, setPosts] = useState&amp;lt;any&amp;gt;([]);

  const getPosts = async () =&amp;gt; {
    const { data, error } = await supabase.from('posts').select('*');
    if (error) {
      console.error('Error fetching data:', error.message);
    } else {
      setPosts(data);
    }
  }

  useEffect(() =&amp;gt; {
    getPosts()
  }, [])

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="container mx-auto mt-8 max-w-[560px] bg-white p-4 rounded-lg min-h-60"&amp;gt;
        &amp;lt;div className="flex justify-between items-center pb-4 border-b border-dashed border-gray-900 mb-4"&amp;gt;
          &amp;lt;h1 className="text-3xl font-semibold"&amp;gt;Posts&amp;lt;/h1&amp;gt;
          &amp;lt;Link
            className="bg-black hover:bg-opacity-80 text-white rounded-lg px-4 py-2 duration-200"
            href="/create"
          &amp;gt;
            Create New
          &amp;lt;/Link&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;ul&amp;gt;
          {posts.map((task:any) =&amp;gt; (
            &amp;lt;li key={task.id} className="py-2 flex justify-between w-full"&amp;gt;
              &amp;lt;span&amp;gt;
                &amp;lt;strong&amp;gt;{task.title}&amp;lt;/strong&amp;gt; - {task.description}
              &amp;lt;/span&amp;gt;
              &amp;lt;span className="flex gap-2"&amp;gt;
                &amp;lt;Link className="text-blue-700 underline hover:no-underline flex justify-center items-center gap-2" href={`/edit/${task.id}`}&amp;gt;&amp;lt;CiEdit /&amp;gt;Edit&amp;lt;/Link&amp;gt;
                &amp;lt;Link className="text-red-500 underline hover:no-underline flex justify-center items-center gap-2" href={`/delete/${task.id}`}&amp;gt;&amp;lt;MdDeleteOutline /&amp;gt;Delete&amp;lt;/Link&amp;gt;
              &amp;lt;/span&amp;gt;
            &amp;lt;/li&amp;gt;
          ))}
          {posts?.length &amp;lt; 1 &amp;amp;&amp;amp; &amp;lt;Empty /&amp;gt;}
        &amp;lt;/ul&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Post&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. Create Page to Create New Tasks
&lt;/h2&gt;

&lt;p&gt;Create page app/create/page.jsx and copy paste code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";

import supabase from "@/config/supabase";
import Head from "next/head";
import { useRouter } from "next/navigation"; // Update this import
import { useState } from "react";

export default function Create() {
  const router = useRouter(); // Use `useRouter` from `next/navigation`
  const [post, setPost] = useState&amp;lt;any&amp;gt;({
    title: "",
    description: "",
  });

  const onChange = (e: any) =&amp;gt; {
    setPost({ ...post, [e.target.name]: e.target.value });
  };

  const handleCreate = async () =&amp;gt; {
    try {
      await supabase.from("posts").upsert([post]);
      router.push("/"); // This line is fine
    } catch (error) {
      console.log(error);
    }
  };

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="container mx-auto mt-8 max-w-[560px] bg-white p-4 rounded-lg min-h-60 "&amp;gt;
        &amp;lt;div className="flex justify-between items-center pb-4 border-b border-dashed border-gray-900 mb-4"&amp;gt;
          &amp;lt;h1 className="text-3xl font-semibold"&amp;gt;Create Post&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;form&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label&amp;gt;Title&amp;lt;/label&amp;gt;
            &amp;lt;input
              className="mt-1 px-4 py-2 border border-gray-300 rounded-md block w-full"
              type="text"
              name="title"
              value={post?.tile}
              onChange={onChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label&amp;gt;Description&amp;lt;/label&amp;gt;
            &amp;lt;input
              className="mt-1 px-4 py-2 border border-gray-300 rounded-md block w-full"
              type="text"
              name="description"
              value={post?.description}
              onChange={onChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button
            className="bg-black hover:bg-opacity-80 text-white rounded-lg px-4 py-2 duration-200 w-full"
            type="button"
            onClick={handleCreate}
          &amp;gt;
            Create Post
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Create Post&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;
    &amp;lt;/&amp;gt;
  );
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Create Page to Edit Post
&lt;/h2&gt;

&lt;p&gt;Create page app/edit/[id]/edit.tsx and copy paste code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";

import supabase from "@/config/supabase";
import Head from "next/head";
import { useParams, useRouter } from "next/navigation"; // Use next/navigation for Next.js 13+
import { useEffect, useState } from "react";

interface Task {
  title: string;
  description: string;
}

const Edit = () =&amp;gt; {
  const router = useRouter();

  const { id } = useParams();

  const [post, setPost] = useState&amp;lt;Task&amp;gt;({
    title: "",
    description: "",
  });

  const onChange = (e: React.ChangeEvent&amp;lt;HTMLInputElement&amp;gt;) =&amp;gt; {
    setPost({ ...post, [e.target.name]: e.target.value });
  };

  useEffect(() =&amp;gt; {
    const fetchPost = async () =&amp;gt; {
      if (typeof id === "string") {
        const { data, error } = await supabase
          .from("posts")
          .select("*")
          .eq("id", id)
          .single();

        if (error) {
          console.error("Error fetching task:", error.message);
          return;
        }

        if (data) {
          setPost(data);
        }
      }
    };

    if (id) {
      fetchPost();
    }
  }, [id]);

  const handleUpdate = async () =&amp;gt; {
    try {
      if (typeof id === "string") {
        const { error } = await supabase.from("posts").update(post).eq("id", id);

        if (error) {
          console.error("Error updating task:", error.message);
          return;
        }

        router.push("/");
      }
    } catch (error) {
      console.error("Error:", error);
    }
  };

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="container mx-auto mt-8 max-w-[560px] bg-white p-4 rounded-lg min-h-60"&amp;gt;
        &amp;lt;div className="flex justify-between items-center pb-4 border-b border-dashed border-gray-900 mb-4"&amp;gt;
          &amp;lt;h1 className="text-3xl font-semibold"&amp;gt;Edit Post&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;form&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label htmlFor="name"&amp;gt;Title: &amp;lt;/label&amp;gt;
            &amp;lt;input
              className="mt-1 px-4 py-2 border border-gray-300 rounded-md block w-full"
              type="text"
              id="title"
              name="title"
              value={post.title}
              onChange={onChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="mb-4"&amp;gt;
            &amp;lt;label htmlFor="description"&amp;gt;Description: &amp;lt;/label&amp;gt;
            &amp;lt;input
              className="mt-1 px-4 py-2 border border-gray-300 rounded-md block w-full"
              type="text"
              id="description"
              name="description"
              value={post.description}
              onChange={onChange}
            /&amp;gt;
          &amp;lt;/div&amp;gt;
          &amp;lt;button
            className="bg-black hover:bg-opacity-80 text-white rounded-lg px-4 py-2 duration-200 w-full"
            type="button"
            onClick={handleUpdate}
          &amp;gt;
            Edit Post
          &amp;lt;/button&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Edit Post&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

export default Edit;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  11. Create Page to Delete Posts
&lt;/h2&gt;

&lt;p&gt;Create page app/delete/[id]/page.tsx and copy paste code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client"
import supabase from "@/config/supabase";
import Head from "next/head";
import Link from "next/link";
import { useParams, useRouter } from "next/navigation";
import { useEffect, useState } from "react";

const Delete = () =&amp;gt; {
  const router = useRouter();
  const { id } = useParams();

  const [post, setPost] = useState&amp;lt;any&amp;gt;({
    title: "",
    description: "",
  });

  useEffect(() =&amp;gt; {
    const fetchPost = async () =&amp;gt; {
      const { data } = await supabase.from("posts").select("*").eq("id", id);
      setPost(data);
    };

    if (id) {
      fetchPost();
    }
  }, [id]);

  const handleDelete = async () =&amp;gt; {
    try {
      await supabase.from("posts").delete().eq("id", id);
      router.push("/");
    } catch (error) {
      console.log(error);
    }
  };

  return (
    &amp;lt;&amp;gt;
      &amp;lt;div className="container mx-auto mt-8 max-w-[560px] bg-white p-4 rounded-lg min-h-60"&amp;gt;
        &amp;lt;div className="flex justify-between items-center pb-4 border-b border-dashed border-gray-900 mb-4"&amp;gt;
          &amp;lt;h1 className="text-3xl font-semibold"&amp;gt;Delete Post&amp;lt;/h1&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;form&amp;gt;
          &amp;lt;div className="my-12"&amp;gt;
            Are you sure to delete &amp;lt;strong&amp;gt;{post?.name}&amp;lt;/strong&amp;gt;?
          &amp;lt;/div&amp;gt;
          &amp;lt;div className="flex w-full gap-2"&amp;gt;
            &amp;lt;Link
              href="/"
              className="text-center bg-gray-300 hover:bg-opacity-80 text-black rounded-lg px-4 py-2 duration-200 w-full"
            &amp;gt;
              Cancel
            &amp;lt;/Link&amp;gt;
            &amp;lt;button
              className="bg-black hover:bg-opacity-80 text-white rounded-lg px-4 py-2 duration-200 w-full"
              type="button"
              onClick={handleDelete}
            &amp;gt;
              Delete
            &amp;lt;/button&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/form&amp;gt;
      &amp;lt;/div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;Delete Post&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;
    &amp;lt;/&amp;gt;
  );
};

export default Delete;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  12.Result:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your website would be like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fde8jlbmy85k7nqr5srdq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fde8jlbmy85k7nqr5srdq.PNG" alt="Image description" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6reyqdjog27gqk8knyo.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fh6reyqdjog27gqk8knyo.PNG" alt="Image description" width="800" height="380"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y6qxt8aq8o8f20fmq41.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6y6qxt8aq8o8f20fmq41.PNG" alt="Image description" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faolir0dc4rkfmft9dueq.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faolir0dc4rkfmft9dueq.PNG" alt="Image description" width="800" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations on making it to the end of this guide on creating a CRUD application with Next.js and Supabase! I hope this article has given you a solid foundation and the confidence to build and expand your own web applications using these powerful tools. Thank you for taking the time to read through this tutorial—your interest and engagement mean a lot!&lt;/p&gt;

&lt;p&gt;If you have any questions, feedback, or want to connect, feel free to reach out on &lt;a href="https://www.linkedin.com/in/seif-eddine-saad-3728aa19b" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or check out more of my projects on &lt;a href="https://github.com/seifeddinesaad01" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I’d love to hear from you and see what amazing things you build!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
