MCPcopy Index your code
hub / github.com/adrianhajdin/ai_saas_app

github.com/adrianhajdin/ai_saas_app @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
86 symbols 300 edges 50 files 0 documented · 0%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README
<a href="https://youtu.be/Ahwoks_dawU?feature=shared" target="_blank">
  <img src="https://github.com/sujatagunale/EasyRead/assets/151519281/daf9e91b-6342-4e9a-9361-8dc2bd01ce64" alt="Project Banner">
</a>







<img src="https://img.shields.io/badge/-Next_JS-black?style=for-the-badge&logoColor=white&logo=nextdotjs&color=000000" alt="nextdotjs" />
<img src="https://img.shields.io/badge/-TypeScript-black?style=for-the-badge&logoColor=white&logo=typescript&color=3178C6" alt="typescript" />
<img src="https://img.shields.io/badge/-Stripe-black?style=for-the-badge&logoColor=white&logo=stripe&color=008CDD" alt="stripe" />
<img src="https://img.shields.io/badge/-MongoDB-black?style=for-the-badge&logoColor=white&logo=mongodb&color=47A248" alt="mongodb" />
<img src="https://img.shields.io/badge/-Tailwind_CSS-black?style=for-the-badge&logoColor=white&logo=tailwindcss&color=06B6D4" alt="tailwindcss" />

An AI SaaS Platform

 Build this project step by step with our detailed tutorial on <a href="https://www.youtube.com/@javascriptmastery/videos" target="_blank"><b>JavaScript Mastery</b></a> YouTube. Join the JSM family!

📋 Table of Contents

  1. 🤖 Introduction
  2. ⚙️ Tech Stack
  3. 🔋 Features
  4. 🤸 Quick Start
  5. 🕸️ Snippets
  6. 🔗 Links
  7. 🚀 More

🚨 Tutorial

This repository contains the code corresponding to an in-depth tutorial available on our YouTube channel, JavaScript Mastery.

If you prefer visual learning, this is the perfect resource for you. Follow our tutorial to learn how to build projects like these step-by-step in a beginner-friendly manner!

🤖 Introduction

Build an AI image SaaS platform that excels in image processing capabilities, integrates a secure payment infrastructure, offers advanced image search functionalities, and supports multiple AI features, including image restoration, recoloring, object removal, generative filling, and background removal. This project can be a guide for your next AI image tool and a boost to your portfolio.

If you're getting started and need assistance or face any bugs, join our active Discord community with over 27k+ members. It's a place where people help each other out.

⚙️ Tech Stack

  • Next.js
  • TypeScript
  • MongoDB
  • Clerk
  • Cloudinary
  • Stripe
  • Shadcn
  • TailwindCSS

🔋 Features

👉 Authentication and Authorization: Secure user access with registration, login, and route protection.

👉 Community Image Showcase: Explore user transformations with easy navigation using pagination

👉 Advanced Image Search: Find images by content or objects present inside the image quickly and accurately

👉 Image Restoration: Revive old or damaged images effortlessly

👉 Image Recoloring: Customize images by replacing objects with desired colors easily

👉 Image Generative Fill: Fill in missing areas of images seamlessly

👉 Object Removal: Clean up images by removing unwanted objects with precision

👉 Background Removal: Extract objects from backgrounds with ease

👉 Download Transformed Images: Save and share AI-transformed images conveniently

👉 Transformed Image Details: View details of transformations for each image

👉 Transformation Management: Control over deletion and updates of transformations

👉 Credits System: Earn or purchase credits for image transformations

👉 Profile Page: Access transformed images and credit information personally

👉 Credits Purchase: Securely buy credits via Stripe for uninterrupted use

👉 Responsive UI/UX: A seamless experience across devices with a user-friendly interface

and many more, including code architecture and reusability

🤸 Quick Start

Follow these steps to set up the project locally on your machine.

Prerequisites

Make sure you have the following installed on your machine:

Cloning the Repository

git clone https://github.com/adrianhajdin/imaginify.git
cd imaginify

Installation

Install the project dependencies using npm:

npm run dev

Set Up Environment Variables

Create a new file named .env.local in the root of your project and add the following content:

#NEXT
NEXT_PUBLIC_SERVER_URL=

#MONGODB
MONGODB_URL=

#CLERK
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=
CLERK_SECRET_KEY=
WEBHOOK_SECRET=

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/

#CLOUDINARY
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=

#STRIPE
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=

Replace the placeholder values with your actual respective account credentials. You can obtain these credentials by signing up on the Clerk, MongoDB, Cloudinary and Stripe

Running the Project

npm run dev

Open http://localhost:3000 in your browser to view the project.

🕸️ Snippets

tailwind.config.ts

/** @type {import('tailwindcss').Config} */
module.exports = {
  darkMode: ["class"],
  content: [
    "./pages/**/*.{ts,tsx}",
    "./components/**/*.{ts,tsx}",
    "./app/**/*.{ts,tsx}",
    "./src/**/*.{ts,tsx}",
  ],
  prefix: "",
  theme: {
    container: {
      center: true,
      padding: "2rem",
      screens: {
        "2xl": "1400px",
      },
    },
    extend: {
      colors: {
        border: "hsl(var(--border))",
        input: "hsl(var(--input))",
        ring: "hsl(var(--ring))",
        background: "hsl(var(--background))",
        foreground: "hsl(var(--foreground))",
        purple: {
          100: "#F4F7FE",
          200: "#BCB6FF",
          400: "#868CFF",
          500: "#7857FF",
          600: "#4318FF",
        },
        dark: {
          400: "#7986AC",
          500: "#606C80",
          600: "#2B3674",
          700: "#384262",
        },
        primary: {
          DEFAULT: "hsl(var(--primary))",
          foreground: "hsl(var(--primary-foreground))",
        },
        secondary: {
          DEFAULT: "hsl(var(--secondary))",
          foreground: "hsl(var(--secondary-foreground))",
        },
        destructive: {
          DEFAULT: "hsl(var(--destructive))",
          foreground: "hsl(var(--destructive-foreground))",
        },
        muted: {
          DEFAULT: "hsl(var(--muted))",
          foreground: "hsl(var(--muted-foreground))",
        },
        accent: {
          DEFAULT: "hsl(var(--accent))",
          foreground: "hsl(var(--accent-foreground))",
        },
        popover: {
          DEFAULT: "hsl(var(--popover))",
          foreground: "hsl(var(--popover-foreground))",
        },
        card: {
          DEFAULT: "hsl(var(--card))",
          foreground: "hsl(var(--card-foreground))",
        },
      },
      fontFamily: {
        IBMPlex: ["var(--font-ibm-plex)"],
      },
      backgroundImage: {
        "purple-gradient": "url('/assets/images/gradient-bg.svg')",
        banner: "url('/assets/images/banner-bg.png')",
      },
      borderRadius: {
        lg: "var(--radius)",
        md: "calc(var(--radius) - 2px)",
        sm: "calc(var(--radius) - 4px)",
      },
      keyframes: {
        "accordion-down": {
          from: { height: "0" },
          to: { height: "var(--radix-accordion-content-height)" },
        },
        "accordion-up": {
          from: { height: "var(--radix-accordion-content-height)" },
          to: { height: "0" },
        },
      },
      animation: {
        "accordion-down": "accordion-down 0.2s ease-out",
        "accordion-up": "accordion-up 0.2s ease-out",
      },
    },
  },
  plugins: [require("tailwindcss-animate")],
};

globals.css

```css @tailwind base; @tailwind components; @tailwind utilities;

@layer base { :root { --background: 0 0% 100%; --foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;

}

.dark { --background: 222.2 84% 4.9%; --foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;

} }

@layer base { * { @apply border-border; } body { @apply bg-background text-foreground; } }

.auth { @apply flex-center min-h-screen w-full bg-purple-100 }

.root { @apply flex min-h-screen w-full flex-col bg-white lg:flex-row; }

.root-container { @apply mt-16 flex-1 overflow-auto py-8 lg:mt-0 lg:max-h-screen lg:py-10 }

/ ========================================== TAILWIND STYLES / @layer utilities { / ===== UTILITIES / .wrapper { @apply max-w-5xl mx-auto px-5 md:px-10 w-full text-dark-400 p-16-regular; }

.gradient-text { @apply bg-purple-gradient bg-cover bg-clip-text text-transparent; }

/ ===== ALIGNMENTS / .flex-center { @apply flex justify-center items-center; }

.flex-between { @apply flex justify-between items-center; }

/ ===== TYPOGRAPHY / / 44 / .h1-semibold { @apply text-[36px] font-semibold sm:text-[44px] leading-[120%] sm:leading-[56px]; }

/ 36 / .h2-bold { @apply text-[30px] font-bold md:text-[36px] leading-[110%]; }

/ 30 / .h3-bold { @apply font-bold text-[30px] leading-[140%]; }

/ 24 / .p-24-bold { @apply font-bold text-[24px] leading-[120%]; }

/ 20 / .p-20-semibold { @apply font-semibold text-[20px] leading-[140%]; }

.p-20-regular { @apply font-normal text-[20px] leading-[140%]; }

/ 18 / .p-18-semibold { @apply font-semibold text-[18px] leading-[140%]; }

/ 16 / .p-16-semibold { @apply font-semibold text-[16px] leading-[140%]; }

.p-16-medium { @apply font-medium text-[16px] leading-[140%]; }

.p-16-regular { @apply font-normal text-[16px] leading-[140%]; }

/ 14 / .p-14-medium { @apply font-medium text-[14px] leading-[120%]; }

/ 10 / .p-10-medium { @apply font-medium text-[10px] leading-[140%]; }

/ ===== SHADCN OVERRIDES / .button { @apply py-4 px-6 flex-center gap-3 rounded-full p-16-semibold focus-visible:ring-offset-0 focus-visible:ring-transparent !important; }

.dropdown-content { @apply shadow-lg rounded-md overflow-hidden p-0; }

.dropdown-item { @apply p-16-semibold text-dark-700 cursor-pointer transition-all px-4 py-3 rounded-none outline-none hover:border-none focus-visible:ring-transparent hover:text-white hover:bg-purple-gradient hover:bg-cover focus-visible:ring-offset-0 focus-visible:outline-none !important; }

.input-field { @apply rounded-[16px] border-2 border-purple-200/20 shadow-sm shadow-purple-200/15 text-dark-600 disabled:opacity-100 p-16-semibold h-[50px] md:h-[54px] focus-visible:ring-offset-0 px-4 py-3 focus-visible:ring-transparent !important; }

.search-field { @apply border-0 bg-transparent text-dark-600 w-full placeholder:text-dark-400 h-[50px] p-16-medium focus-visible:ring-offset-0 p-3 focus-visible:ring-transparent !important; }

.submit-button { @apply bg-purple-gradient bg-cover rounded-full py-4 px-6 p-16-semibold h-[50px] w-full md:h-[54px]; }

.select-field { @apply w-full border-2 border-purple-200/20 shadow-sm shadow-purple-200/15 rounded-[16px] h-[50px] md:h-[54px] text-dark-600 p-16-semibold disabled:opacity-100 placeholder:text-dark-400/50 px-4 py-3 focus:ring-offset-0 focus-visible:ring-transparent focus:ring-transparent focus-visible:ring-0 focus-visible:outline-none !important; }

.select-trigger { @apply flex items-center gap-2 py-5 capitalize focus-visible:outline-none; }

.select-item { @apply py-3 cursor-pointer hover:bg-purple-100; }

.IconButton { @apply focus-visible:ring-transparent focus:ring-offset-0 focus-visible:ring-offset-0 focus-visible:outline-none focus-visible:border-none !important; }

.sheet

Extension points exported contracts — how you extend this code

InputProps (Interface)
(no doc)
components/ui/input.tsx
MongooseConnection (Interface)
(no doc)
lib/database/mongoose.ts
State (Interface)
(no doc)
components/ui/use-toast.ts
IImage (Interface)
(no doc)
lib/database/models/image.model.ts
SheetContentProps (Interface)
(no doc)
components/ui/sheet.tsx
ButtonProps (Interface)
(no doc)
components/ui/button.tsx

Core symbols most depended-on inside this repo

cn
called by 43
lib/utils.ts
handleError
called by 12
lib/utils.ts
connectToDatabase
called by 12
lib/database/mongoose.ts
getImageSize
called by 6
lib/utils.ts
dispatch
called by 5
components/ui/use-toast.ts
toast
called by 4
components/ui/use-toast.ts
useFormField
called by 4
components/ui/form.tsx
getUserById
called by 4
lib/actions/user.actions.ts

Shape

Function 80
Interface 6

Languages

TypeScript100%

Modules by API surface

lib/utils.ts10 symbols
components/ui/use-toast.ts9 symbols
lib/actions/image.actions.ts7 symbols
lib/actions/user.actions.ts5 symbols
components/ui/pagination.tsx5 symbols
components/shared/TransformationForm.tsx5 symbols
components/ui/sheet.tsx3 symbols
components/shared/MediaUploader.tsx3 symbols
components/shared/Collection.tsx3 symbols
lib/database/mongoose.ts2 symbols
lib/actions/transaction.action.ts2 symbols
components/ui/form.tsx2 symbols

Datastores touched

(mongodb)Database · 1 repos

For agents

$ claude mcp add ai_saas_app \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page