Yoga Studio Template

Complete documentation for the full-stack Next.js yoga studio website template with admin dashboard.

Overview

Yoga Studio is a production-ready, full-stack website template designed for yoga studios, fitness centers, and wellness businesses. Built with Next.js 16, React 19, MongoDB, and Tailwind CSS 4, it provides a stunning public-facing landing page and a powerful admin dashboard for complete content management.

Every element of the public website — from hero banners to team members, gallery images, class schedules, and more — is fully manageable through the admin panel without writing a single line of code.

Tech Stack

LayerTechnology
FrameworkNext.js 16.2.3 (App Router)
FrontendReact 19.2.5, Tailwind CSS 4.1.13
UI ComponentsRadix UI, shadcn/ui patterns (40+ components)
State ManagementZustand 5.0.8
Forms & ValidationReact Hook Form + Zod
BackendNext.js API Routes (Node.js)
DatabaseMongoDB with Mongoose ODM
AuthenticationNextAuth 5 + JWT (jsonwebtoken) + bcrypt
File StorageCloudinary CDN
Rich Text EditorSunEditor
Data TablesTanStack React Table
ChartsRecharts
Drag & DropDnD Kit
IconsLucide React, React Icons
CarouselsSplide, Embla Carousel
VideoReact Player

Features

Public Website

  • Responsive landing page with 15+ configurable sections
  • Hero banner with dynamic content
  • About Us & Founder sections
  • Types of Yoga showcase with icons
  • Classes & Programs display
  • Yoga at Home section
  • Image & Video galleries
  • Why Choose Us section with stats
  • Pricing plans
  • Testimonials & FAQ sections
  • Contact form with submissions management
  • Newsletter subscription
  • Team member directory
  • SEO metadata management
  • Dark/Light theme support

Admin Dashboard

  • Secure JWT-based authentication
  • Dashboard with real-time statistics
  • Full CRUD for all content types
  • Drag-and-drop reordering
  • Active/Inactive status toggle
  • Rich text editor (SunEditor)
  • Image upload with Cloudinary integration
  • Contact & subscription management
  • Business hours configuration
  • General settings (logo, favicon, social links)
  • SEO metadata editor
  • Terms & Privacy policy editor
  • Page banner management

Requirements

RequirementVersion / Details
Node.js18.x or higher
Package Managerpnpm (recommended), npm, or yarn
MongoDBAtlas (cloud) or local instance
CloudinaryFree or paid account for media storage

Installation

Step 1: Clone the Repository

git clone <repository-url>
cd template-yoga

Step 2: Install Dependencies

pnpm install

Step 3: Configure Environment Variables

Create a .env file in the root directory (see Environment Variables section below).

Step 4: Run the Development Server

pnpm dev

The application will start at http://localhost:3000.

Step 5: Build for Production

pnpm build
pnpm start
Note: On first run, the application automatically creates a default admin account. See Default Credentials.

Environment Variables

Create a .env file in the project root with the following variables:

VariableDescriptionExample
AUTH_TRUST_HOSTTrust the host header for authenticationtrue
NEXTAUTH_SECRETSecret key for JWT signing (generate a secure random string)your-secret-key-here
NEXTAUTH_URLBase URL for NextAuth callbackshttp://localhost:3000
NEXT_PUBLIC_BASE_URLPublic-facing base URLhttp://localhost:3000
MONGODB_URIMongoDB connection stringmongodb+srv://user:pass@host/dbname
Note: Cloudinary credentials are configured through the Admin Dashboard > Settings page, not via environment variables.

Default Admin Credentials

On first startup, the application seeds a default admin account:

FieldValue
Emailadmin@example.com
PasswordChangeMe123!
Important: Change these credentials immediately after your first login through Admin Dashboard > Profile settings.

Available Scripts

CommandDescription
pnpm devStart development server on port 3000 (with hot reload)
pnpm buildCreate optimized production build
pnpm startStart production server
pnpm lintRun ESLint for code quality checks

Project Structure

template-yoga/ ├── app/ # Next.js App Router │ ├── (admin)/ # Admin login route group │ │ └── admin/login/ # Login page & components │ ├── (private)/ # Protected admin routes │ │ └── admin/dashboard/ # Dashboard & management pages │ │ ├── intro/ # Hero section editor │ │ ├── about-us/ # About section editor │ │ ├── why-choose-us/ # Why Choose Us editor │ │ ├── types-of-yoga/ # Yoga types CRUD │ │ ├── classes-and-programs/ # Classes section editor │ │ ├── yoga-at-home/ # Yoga at Home editor │ │ ├── team/ # Team members CRUD │ │ ├── gallery/ # Image gallery CRUD │ │ ├── contact/ # Contact submissions │ │ ├── subscriptions/ # Newsletter subscribers │ │ └── settings/ # Site settings │ ├── (public)/ # Public-facing routes │ │ ├── page.tsx # Landing page │ │ └── team/ # Team directory │ ├── api/ # API endpoints │ │ ├── admin/ # Protected admin APIs │ │ │ ├── auth/ # Login, profile, password │ │ │ ├── yoga/ # Yoga CRUD + sort + status │ │ │ ├── team/ # Team CRUD + sort + status │ │ │ ├── gallery/ # Gallery CRUD + sort + status │ │ │ ├── video-gallery/ # Video CRUD + sort + status │ │ │ ├── yoga-schedule/ # Schedule CRUD + sort │ │ │ ├── banner/ # Banner management │ │ │ ├── home-section/ # Dynamic home sections │ │ │ ├── contact-us/ # Contact submissions │ │ │ ├── subscribe/ # Subscriber list │ │ │ ├── file/ # File upload & delete │ │ │ ├── dashboard/ # Statistics endpoint │ │ │ └── settings/ # All settings endpoints │ │ ├── auth/ # NextAuth route handler │ │ └── public/ # Public APIs (no auth) │ ├── documentation/ # Documentation page │ ├── layout.tsx # Root layout │ └── globals.css # Global styles │ ├── actions/ # Next.js Server Actions │ ├── adminLogin/ # Login actions │ ├── dashboard/ # Dashboard data fetching │ ├── yoga/ # Yoga operations │ ├── yogaSchedule/ # Schedule operations │ ├── team/ # Team operations │ ├── gallery/ # Gallery operations │ ├── profile/ # Profile management │ ├── settings/ # Settings management │ ├── contacts/ # Contact management │ ├── subscriptions/ # Subscription management │ ├── whyChoseUs/ # Why Choose Us section │ ├── yogaAtHome/ # Yoga at Home section │ └── public/ # Public data fetching │ ├── components/ # React Components │ ├── ui/ # 40+ Base UI components (shadcn/Radix) │ ├── custom/ # Custom components │ ├── features/ # Feature-specific components │ │ ├── landing/ # 15+ landing page sections │ │ ├── dashboard/ # Dashboard widgets │ │ └── public/ # Public page components │ ├── forms/ # Form field components │ ├── layouts/ # Layout components (header, footer) │ ├── providers/ # Context providers (auth, theme) │ ├── shared/ # Shared utility components │ └── tables/ # Data table components │ ├── model/ # Mongoose Database Models │ ├── User.ts # Admin user model │ ├── Yoga.ts # Yoga types │ ├── Team.ts # Team members │ ├── Gallery.ts # Image gallery │ ├── VideoGallery.ts # Video gallery │ ├── YogaSchedule.ts # Class schedules │ ├── Banner.ts # Banner / hero │ ├── HomeSection.ts # Dynamic home sections │ ├── Settings.ts # Site settings (singleton) │ ├── Subscribe.ts # Newsletter subscribers │ └── Contactus.ts # Contact submissions │ ├── lib/ # Utility Libraries │ ├── async-handler.ts # API wrapper with auth & validation │ ├── async-formdata-handler.ts # FormData processing wrapper │ ├── authenticate.ts # JWT token verification │ ├── api-client.ts # Client-side API wrapper │ ├── server-utils.ts # Server response & JWT helpers │ ├── file-validator.ts # File type & size validation │ ├── mongo-adapter.ts # MongoDB aggregation helpers │ ├── validation-schema.ts # Zod validation schemas │ ├── metadata.ts # SEO metadata generation │ └── utils.ts # General utility functions │ ├── config/ # Configuration │ ├── constant.ts # Roles & cache tag constants │ ├── database.ts # MongoDB connection & seeding │ ├── cloudinary.ts # Cloudinary upload/delete │ ├── routes.ts # Route definitions │ └── cache.ts # In-memory caching │ ├── hooks/ # React Custom Hooks ├── contexts/ # React Contexts ├── types/ # TypeScript Type Definitions ├── public/ # Static Assets (fonts, images) │ ├── .env # Environment variables ├── next.config.ts # Next.js configuration ├── tailwind.config.ts # Tailwind CSS configuration ├── tsconfig.json # TypeScript configuration ├── Dockerfile # Docker containerization ├── postcss.config.mjs # PostCSS configuration ├── components.json # shadcn/ui configuration └── package.json # Dependencies & scripts

Database Models

The application uses MongoDB with Mongoose ODM. Below are all 11 collections and their schemas.

User

FieldTypeDescription
nameStringUser display name
emailString (unique)Login email address
passwordStringBcrypt-hashed password
roleEnumadmin or user

Yoga

FieldTypeDescription
titleStringYoga type name
descriptionStringDetailed description
imageStringCloudinary image public_id
iconStringCloudinary icon public_id
positionNumberDisplay order (default: 0)
statusBooleanActive/inactive (default: true)

Team

FieldTypeDescription
nameStringMember name
imageStringCloudinary image public_id
designationStringJob title / role
detailsStringBiography or details
positionNumberDisplay order (default: 0)
statusBooleanActive/inactive (default: true)

YogaSchedule

FieldTypeDescription
yogaObjectId (ref: Yoga)Reference to Yoga type
instructorObjectId (ref: Team)Reference to Team member
timeSlotsArray[{startTime, endTime, days[]}]
positionNumberDisplay order (default: 0)
statusBooleanActive/inactive (default: true)

Gallery

FieldTypeDescription
imageStringCloudinary image public_id
titleStringOptional caption
statusBooleanActive/inactive (default: true)
orderByNumberDisplay order (default: 0)

VideoGallery

FieldTypeDescription
videoStringVideo URL or Cloudinary public_id
titleStringOptional video title
statusBooleanActive/inactive (default: true)
orderByNumberDisplay order (default: 0)

Banner

FieldTypeDescription
headingStringBanner headline text
shortDescStringShort description
imageOneStringPrimary image (Cloudinary ID)
imageTwoStringSecondary image (Cloudinary ID)
sectionNameEnumbanner or section
categoriesStringOptional categories
positionNumberDisplay order (default: 0)
statusBooleanActive/inactive (default: true)

HomeSection

FieldTypeDescription
sectionKeyString (unique)Unique section identifier
titleStringSection title
subTitleStringSection subtitle
sectionImageStringSection hero image
imagesArrayArray of Cloudinary image IDs
videosArrayArray of video URLs
featuresArray[{title, description}]
statsArray[{value, suffix, label}]
contentObjectFlexible content object
statusBooleanActive/inactive (default: true)
orderByNumberDisplay order (default: 0)

Settings (Singleton)

SectionKey Fields
generalcompanyName, phone, address, email, logo, favicon, social links
pageBannermenu, location, gallery, reserveTable (Cloudinary IDs)
cloudinarycloudName, apiKey, apiSecret, folderName, secureUrlBase
metadatatitle, applicationName, description, keywords[], openGraphImage
termsPolicyterms, policy (HTML content)
businessHoursArray of {dayOfWeek, openTime, closeTime, isClosed}

Subscribe

FieldTypeDescription
emailString (unique)Subscriber email address

Contactus

FieldTypeDescription
nameStringSender name
emailStringSender email
messageStringMessage content
isCheckBooleanRead/unread status (default: false)
Note: All models include automatic createdAt and updatedAt timestamps via Mongoose.

Authentication System

The application uses JWT-based authentication with NextAuth 5.

Login Flow

  1. Admin submits email and password to POST /api/admin/auth/login
  2. Server verifies credentials against bcrypt-hashed password in database
  3. On success, a JWT token is generated with 30-day expiration
  4. Token payload contains: { email, role: 'admin' }
  5. Client stores the token and sends it in subsequent requests via Authorization: Bearer {token} header

Route Protection

  • Admin API routes use the asyncHandler() middleware with authentication enabled
  • JWT is verified on every request using the NEXTAUTH_SECRET
  • Invalid or expired tokens return 401 Unauthorized
  • User data is extracted from the token and attached to the request context

Password Security

  • Passwords are hashed using bcrypt with 10 salt rounds
  • Password change requires the current password for verification
  • New password confirmation is enforced via Zod validation

Cloudinary Integration

All media files (images and videos) are stored on Cloudinary CDN for optimized delivery and management.

Setup

  1. Create a free account at cloudinary.com
  2. Navigate to Admin Dashboard > Settings in your application
  3. Enter your Cloudinary credentials: Cloud Name, API Key, API Secret
  4. Set a Folder Name for organized storage
  5. Enter the Secure URL Base (e.g., https://res.cloudinary.com/your-cloud)

Features

  • Automatic image optimization and responsive delivery
  • Secure URL generation for all assets
  • Folder-based organization
  • Upload and delete operations via the admin panel
  • File type and size validation before upload

Utility Functions

FunctionDescription
uploadImage()Upload a single image to Cloudinary
uploadToCloudinary()Alternative upload with custom options
deleteFromCloudinary()Delete a file by its public_id
cloudinarySecureUrlBase()Get the configured base URL
getCloudinaryFolderName()Get the configured folder name

API Reference: Authentication

Base URL: /api/admin/auth

MethodEndpointDescriptionAuth
POST/api/admin/auth/loginAdmin loginNo
GET/api/admin/auth/meGet admin profileYes
PUT/api/admin/auth/meUpdate admin profileYes
PUT/api/admin/auth/passwordChange passwordYes

POST /api/admin/auth/login

Request body:

{
  "email": "admin@example.com",
  "password": "ChangeMe123!"
}

Success response:

{
  "success": true,
  "data": { "token": "eyJhbGciOiJIUzI1NiIs..." }
}

PUT /api/admin/auth/password

Request body:

{
  "oldPassword": "ChangeMe123!",
  "newPassword": "NewSecurePass456!",
  "confirmPassword": "NewSecurePass456!"
}

API Reference: Yoga Management

Base URL: /api/admin/yoga — All endpoints require Bearer token authentication.

MethodEndpointDescription
POST/api/admin/yogaCreate yoga type (multipart/form-data)
GET/api/admin/yogaList all yoga types
GET/api/admin/yoga/:idGet single yoga type
PUT/api/admin/yoga/:idUpdate yoga type (multipart/form-data)
DELETE/api/admin/yoga/:idDelete yoga type
PUT/api/admin/yoga/sortReorder yoga types
PUT/api/admin/yoga/status/:idToggle active/inactive status

Create/Update Yoga (multipart/form-data)

FieldTypeRequiredDescription
titleStringYesYoga type name
descriptionStringNoDescription text
imageFileYesYoga image file
iconFileYesYoga icon file
positionNumberNoDisplay order
statusBooleanNoActive by default

Reorder (PUT /api/admin/yoga/sort)

{ "sortedIds": ["id1", "id2", "id3"] }

Toggle Status (PUT /api/admin/yoga/status/:id)

{ "status": true }

API Reference: Team Management

Base URL: /api/admin/team — All endpoints require Bearer token authentication.

MethodEndpointDescription
POST/api/admin/teamCreate team member (multipart/form-data)
GET/api/admin/teamList all team members
GET/api/admin/team/:idGet single team member
PUT/api/admin/team/:idUpdate team member (multipart/form-data)
DELETE/api/admin/team/:idDelete team member
PUT/api/admin/team/sortReorder team members
PUT/api/admin/team/status/:idToggle active/inactive status

Create/Update Team Member (multipart/form-data)

FieldTypeRequiredDescription
nameStringYesMember name
designationStringYesJob title / role
detailsStringYesBiography text
imageFileYesProfile photo
statusBooleanNoActive by default

API Reference: Yoga Schedule Management

Base URL: /api/admin/yoga-schedule — All endpoints require Bearer token authentication.

MethodEndpointDescription
POST/api/admin/yoga-scheduleCreate schedule
GET/api/admin/yoga-scheduleList all schedules (with lookups)
GET/api/admin/yoga-schedule/:idGet single schedule
PUT/api/admin/yoga-schedule/:idUpdate schedule
DELETE/api/admin/yoga-schedule/:idDelete schedule
PUT/api/admin/yoga-schedule/sortReorder schedules

Create Schedule (POST /api/admin/yoga-schedule)

{
  "yoga": "ObjectId",
  "instructor": "ObjectId",
  "timeSlots": [
    {
      "startTime": "09:00",
      "endTime": "10:00",
      "days": ["MON", "WED", "FRI"]
    }
  ],
  "position": 1,
  "status": true
}

API Reference: Banner Management

Base URL: /api/admin/banner — Requires Bearer token authentication.

MethodEndpointDescription
POST/api/admin/bannerCreate or update banner (multipart/form-data)
GET/api/admin/bannerGet current banner

API Reference: Home Section Management

Base URL: /api/admin/home-section — Requires Bearer token authentication.

MethodEndpointDescription
POST/api/admin/home-sectionCreate or update a home section
GET/api/admin/home-section/name/:slugGet section by slug key

Create/Update Home Section

{
  "sectionKey": "about-us",
  "title": "About Our Studio",
  "subTitle": "Where Mind Meets Body",
  "features": [
    { "title": "Expert Teachers", "description": "Certified instructors" }
  ],
  "stats": [
    { "value": "500", "suffix": "+", "label": "Students Trained" }
  ],
  "status": true,
  "orderBy": 1
}

API Reference: Contact Management

Base URL: /api/admin/contact-us — Requires Bearer token authentication.

MethodEndpointDescription
GET/api/admin/contact-usList contacts (paginated)
GET/api/admin/contact-us/:idGet single contact
PUT/api/admin/contact-us/:idUpdate (mark as read)
DELETE/api/admin/contact-us/:idDelete contact

Pagination Query Parameters

ParameterTypeDefaultDescription
pageNumber1Page number
limitNumber10Items per page
searchStringSearch keyword
sortByStringSort field name
sortOrderStringasc or desc

API Reference: Subscription Management

Base URL: /api/admin/subscribe — Requires Bearer token authentication.

MethodEndpointDescription
GET/api/admin/subscribeList newsletter subscribers (paginated)

Supports the same pagination query parameters as the Contact endpoint.

API Reference: File Management

Base URL: /api/admin/file — Requires Bearer token authentication.

MethodEndpointDescription
POST/api/admin/fileUpload image(s) to Cloudinary
DELETE/api/admin/fileDelete image(s) from Cloudinary

Upload (POST, multipart/form-data)

FieldTypeDescription
imageFileSingle image upload
imagesFile[]Multiple images upload

Response:

{
  "success": true,
  "data": {
    "single": { "imageId": "public_id", "url": "https://..." },
    "multiple": [{ "imageId": "public_id", "url": "https://..." }],
    "all": [{ "imageId": "public_id", "url": "https://..." }]
  }
}

Delete (DELETE)

{
  "imageId": "single_public_id",
  "imageIds": ["id1", "id2"]
}

API Reference: Dashboard Statistics

MethodEndpointDescription
GET/api/admin/dashboard/statsGet dashboard overview statistics

Response:

{
  "success": true,
  "data": {
    "yoga": { "active": 5, "inactive": 2, "total": 7 },
    "gallery": { "active": 12, "inactive": 1, "total": 13 },
    "team": { "active": 4, "inactive": 0, "total": 4 }
  }
}

API Reference: Settings

All settings endpoints require Bearer token authentication.

General Settings

MethodEndpointDescription
GET/api/admin/settings/generalGet general settings
PUT/api/admin/settings/generalUpdate general settings (multipart/form-data)

Update Fields (multipart/form-data)

FieldTypeDescription
companyNameStringCompany name
companyDialCodeStringPhone dial code
companyPhoneStringPhone number
companyAddressStringCompany address
supportEmailStringSupport email
ownerNameStringOwner name
ownerEmailStringOwner email
logoFileCompany logo image
faviconFileSite favicon image
facebookStringFacebook page URL
instagramStringInstagram profile URL
twitterStringTwitter/X profile URL
youtubeStringYouTube channel URL

Cloudinary Settings

MethodEndpointDescription
GET/api/admin/settings/cloudinaryGet Cloudinary configuration
PUT/api/admin/settings/cloudinaryUpdate Cloudinary configuration
{
  "cloudName": "your-cloud",
  "apiKey": "123456789",
  "apiSecret": "secret",
  "folderName": "yoga-studio",
  "secureUrlBase": "https://res.cloudinary.com/your-cloud"
}

Business Hours

MethodEndpointDescription
GET/api/admin/settings/business-hourGet business hours
PUT/api/admin/settings/business-hourUpdate business hours
{
  "businessHour": [
    { "dayOfWeek": 0, "openTime": 540, "closeTime": 1080, "isClosed": false },
    { "dayOfWeek": 6, "openTime": 0, "closeTime": 0, "isClosed": true }
  ]
}
Note: openTime and closeTime are in minutes from midnight (e.g., 540 = 9:00 AM, 1080 = 6:00 PM).

SEO Metadata

MethodEndpointDescription
GET/api/admin/settings/metadataGet SEO metadata
PUT/api/admin/settings/metadataUpdate SEO metadata (multipart/form-data)

Page Banners

MethodEndpointDescription
GET/api/admin/settings/page-bannerGet page banner images
PUT/api/admin/settings/page-bannerUpdate page banners (multipart/form-data)

Terms & Policies

MethodEndpointDescription
GET/api/admin/settings/termsGet terms & privacy policy
PUT/api/admin/settings/termsUpdate terms & privacy policy
{
  "terms": "<p>Your terms of service HTML content...</p>",
  "policy": "<p>Your privacy policy HTML content...</p>"
}

API Reference: Public Endpoints

These endpoints do not require authentication and are used by the public-facing website.

MethodEndpointDescription
GET/api/public/yogaList active yoga types
GET/api/public/teamList active team members
GET/api/public/galleryList active gallery images
GET/api/public/video-galleryList active videos
GET/api/public/yoga-scheduleList active schedules
GET/api/public/bannerGet banner data
GET/api/public/home-section/:slugGet home section by key
POST/api/public/subscribeSubscribe to newsletter
POST/api/public/contact-usSubmit contact form
GET/api/public/settings?context=...Get public settings

POST /api/public/subscribe

{ "email": "user@example.com" }

POST /api/public/contact-us

{
  "name": "John Doe",
  "email": "john@example.com",
  "message": "I'd like to know more about your classes."
}

GET /api/public/settings

The context query parameter accepts one of:

  • general — Company info, logo, social links
  • pageBanner — Page banner images
  • cloudinary — Cloudinary base URL
  • metadata — SEO metadata
  • termsPolicy — Terms & privacy policy
  • businessHours — Business hours schedule

Admin Dashboard Pages

RouteDescription
/admin/loginAdmin authentication page
/admin/dashboardOverview with statistics cards and charts
/admin/dashboard/introHero/intro section content editor
/admin/dashboard/about-usAbout Us section editor with features & stats
/admin/dashboard/why-choose-usWhy Choose Us section editor
/admin/dashboard/types-of-yogaYoga types CRUD with drag-and-drop ordering
/admin/dashboard/classes-and-programsClasses & programs section editor
/admin/dashboard/yoga-at-homeYoga at Home section editor
/admin/dashboard/teamTeam members CRUD with drag-and-drop
/admin/dashboard/galleryImage gallery with drag-and-drop ordering
/admin/dashboard/contactContact form submissions with read/unread status
/admin/dashboard/subscriptionsNewsletter subscriber list
/admin/dashboard/settingsGeneral, Cloudinary, business hours, SEO, banners, terms

Public Pages

RouteDescription
/Landing page with all configurable sections
/teamTeam member directory page

Landing Page Sections

The landing page is composed of the following configurable sections (all manageable from admin dashboard):

  1. Hero Banner
  2. About Us
  3. About Founder
  4. Types of Yoga
  5. Classes & Programs
  6. Yoga at Home
  7. Why Choose Us
  8. Image Gallery
  9. Video Gallery
  10. Yoga Categories
  11. Features
  12. Pricing Plans
  13. Testimonials
  14. FAQ
  15. Call to Action
  16. Contact Form

Component Library

The template includes 40+ base UI components built with Radix UI and shadcn/ui patterns, plus custom components for specific functionality.

Base UI Components (components/ui/)

Accordion, Alert, Alert Dialog, Aspect Ratio, Avatar, Badge, Button, Calendar, Card, Carousel, Chart, Checkbox, Collapsible, Command, Context Menu, Dialog, Drawer, Dropdown Menu, Form, Hover Card, Input, Input OTP, Label, Menubar, Navigation Menu, Pagination, Popover, Progress, Radio Group, Resizable, Scroll Area, Select, Separator, Sheet, Sidebar, Skeleton, Slider, Switch, Table, Tabs, Textarea, Toast, Toggle, Toggle Group, Tooltip.

Custom Components (components/custom/)

ComponentDescription
rich-text-editor.tsxSunEditor WYSIWYG editor wrapper
img-dropzone-single.tsxDrag-and-drop file upload zone
PhoneInputField.tsxInternational phone number input
DynamicBreadcrumb.tsxAuto-generating breadcrumb navigation
CustomImage.tsxImage component with Cloudinary URL support
modal.tsxReusable modal dialog
marquee.tsxScrolling marquee text component
custom-button.tsxExtended button with loading states

Data Table Components (components/tables/)

Built with TanStack React Table, includes sortable columns, pagination, search toolbar, faceted filtering, and column visibility options.

Docker Deployment

A Dockerfile is included for containerized deployment.

# Build the Docker image
docker build -t yoga-studio .

# Run the container
docker run -p 3000:3000 --env-file .env yoga-studio
Tip: For production, use a process manager like PM2 or deploy to platforms like Vercel, Railway, or AWS ECS.

Customization

Theming

  • Colors and styles are managed through Tailwind CSS configuration
  • Dark/Light mode is built-in via next-themes
  • Custom CSS variables for theme colors are defined in globals.css

Fonts

Four Google Fonts are loaded in the root layout:

FontCSS VariableUsage
Poppins--font-poppinsPrimary body font
Outfit--font-outfitHeadings
Montserrat--font-montserratAccent text
La Belle Aurore--font-labelleauroreDecorative / script

Adding New Sections

  1. Create a new Mongoose model in model/
  2. Add API routes in app/api/admin/
  3. Create server actions in actions/
  4. Build the admin management page in app/(private)/admin/dashboard/
  5. Add the public-facing component in components/features/landing/

Changelog

Version 1.0.0 — Initial Release

  • Full-stack Next.js 16 application with App Router
  • React 19 with Tailwind CSS 4
  • Admin dashboard with complete content management system
  • 15+ configurable landing page sections
  • MongoDB with Mongoose ODM (11 collections)
  • Cloudinary media management integration
  • JWT-based authentication with NextAuth 5
  • 40+ Radix UI / shadcn components
  • Dark/Light theme support
  • Drag-and-drop content reordering
  • Docker deployment support
  • Fully responsive design
  • SEO optimization with metadata management

Support

For support, questions, or feature requests, please reach out through the item support channel on the marketplace where you purchased this template.

When reporting an issue, please include:

  • Your Node.js version (node -v)
  • Your package manager and version
  • The error message or screenshot
  • Steps to reproduce the issue