A beautiful, modern landing page to showcase your Telegram bots with a powerful admin dashboard. Built with Next.js 15, Clerk Auth, UploadThing, TanStack Query, shadcn/ui, and Neon PostgreSQL.
- π¨ Beautiful Dark Mode - Stunning purple/blue color scheme
- π Lightning Fast - Optimized with Next.js 15 and React Server Components
- π± Fully Responsive - Perfect on mobile, tablet, and desktop
- π Infinite Pagination - Load more bots seamlessly
- π― Type-Safe - Built with TypeScript and Drizzle ORM
- π SEO Optimized - Great for discoverability
- βΏ Accessible - WCAG compliant
- π Modern UI - Powered by shadcn/ui- π Multi-Language - English, Arabic, Kurdish support with next-intl
- β¨ Smooth Animations - Beautiful transitions with motion
- π Clerk Authentication - Secure admin-only access with dark theme
- π€ UploadThing Integration - Upload bot images (4MB max, png/jpeg/webp)
- βοΈ CRUD Operations - Create, edit, delete bots with modal forms
- π Search & Filter - Search by name/description, filter by status
- ποΈ Status Toggle - Switch bots between Active/Down
- π Card Layout - Beautiful grid layout with bot cards
- π Toast Notifications - Success/error feedback with Sonner
- β Zod Validation - Type-safe form validation
- Node.js 18 or higher (or Bun)
- Neon database account (free tier)
- Clerk account (free tier)
- UploadThing account (free tier)
-
Clone the repository
git clone <your-repo-url> cd bots
-
Install dependencies
bun install
-
Set up environment variables
Create
.envfile in the root:# Database DATABASE_URL="postgresql://..." # Clerk Authentication NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY="pk_test_..." CLERK_SECRET_KEY="sk_test_..." # Admin User ID (Your Clerk User ID) ADMIN_USER_ID="user_..." NEXT_PUBLIC_ADMIN_USER_ID="user_..." # UploadThing UPLOADTHING_SECRET="sk_live_..." UPLOADTHING_APP_ID="..."
-
Get Clerk Credentials
- Go to clerk.com and create an account
- Create a new application
- Copy API keys from dashboard
- Sign in to your app and copy your User ID from Clerk Dashboard β Users
- Add your User ID to both
ADMIN_USER_IDandNEXT_PUBLIC_ADMIN_USER_ID
-
Get UploadThing Credentials
- Go to uploadthing.com and create an account
- Create a new app
- Copy Secret and App ID from dashboard
-
Set up the database
bun drizzle-kit generate bun drizzle-kit push
-
Run the development server
bun dev # or npm run dev
- Home (
/) - Hero, features, showcase of active bots, CTA with WhatsApp link - All Bots (
/bots) - All active bots with infinite scroll - Bot Detail (
/bots/[id]) - Individual bot details
Note: Only active bots are displayed on public pages
- Access: Navigate to
/admin/dashboard(only visible when signed in as admin) - Search: Type in search box to find bots by name or description
- Filter: Select status filter (All, Active, Down)
- Create: Click "Add New Bot" β Fill form β Upload images β Submit
- Edit: Click "Edit" on any bot card β Update data β Submit
- Delete: Click "Delete" β Confirm in dialog
- Toggle Status: Use switch on each card to toggle Active/Down
| Category | Technology |
|---|---|
| Framework | Next.js 15 (App Router) |
| Language | TypeScript |
| Styling | Tailwind CSS 4 |
| UI Components | shadcn/ui (Radix UI) |
| Icons | Lucide React |
| Animations | motion (motion/react) |
| Internationalization | next-intl |
| URL State Management | nuqs |
| Data Fetching | TanStack Query |
| Database | Neon (PostgreSQL) |
| ORM | Drizzle ORM |
| Authentication | Clerk |
| File Upload | UploadThing |
| Form Validation | Zod + React Hook Form |
| Toast Notifications | Sonner |
| Package Manager | Bun |
| Deployment | Vercel |
bots/
βββ app/
β βββ admin/
β β βββ dashboard/
β β βββ page.tsx # Admin dashboard
β βββ api/
β β βββ uploadthing/
β β βββ core.ts # UploadThing config
β β βββ route.ts # API route
β βββ bots/ # Bot pages
β βββ layout.tsx # Root layout (Clerk provider)
β βββ page.tsx # Home page
β βββ providers.tsx # TanStack Query
βββ components/
β βββ cards/
β β βββ BotCard.tsx # Bot card for home/dashboard
β β βββ FeatureCard.tsx # Feature card
β βββ forms/
β β βββ BotForm.tsx # Bot create/edit modal
β βββ layouts/
β β βββ header.tsx # Header with admin link
β β βββ footer.tsx
β βββ sections/ # Page sections
β βββ shared/ # Shared components
β βββ ui/ # shadcn/ui components
βββ hooks/
β βββ usePaginationQueries.tsx # Pagination URL params (page, limit)
β βββ useSearchQuery.tsx # Search URL params
β βββ useBotsQueries.tsx # Bot status filter params
β βββ use-date.ts # Date formatting hook
βββ lib/
β βββ react-query/
β β βββ keys.ts # Centralized query keys
β β βββ actions/
β β β βββ bot.action.ts # Bot server actions
β β β βββ uploadthing.action.ts
β β βββ queries/
β β βββ bot.query.ts # Bot TanStack Query hooks
β β βββ uploadthing.query.ts
β βββ db/
β β βββ client.ts # Database client
β β βββ schema.ts # Drizzle schema
β βββ config/
β β βββ cookie.config.ts # Cookie utilities
β β βββ pagination.config.ts
β βββ enums.ts # Enums and constants
β βββ urls.ts # Route constants
β βββ utils.ts # Utility functions (cn)
β βββ uploadthing.ts # UploadThing config
βββ types/
β βββ validation/
β βββ bot.ts # Zod schemas
βββ middleware.ts # Clerk middleware (admin protection)
βββ docs/ # Documentation
bots {
id: UUID; // Auto-generated
userId: string; // Clerk user ID (creator)
name: string; // Bot name
description: string; // Bot description
image: string; // Cover image URL (from UploadThing)
iconImage: string; // Icon URL (from UploadThing)
link: string; // Telegram bot link
repoLink: string; // GitHub repository
status: 'active' | 'down'; // Bot status
createdAt: Date; // Auto-generated
updatedAt: Date; // Auto-updated
}- Admin Protection: Middleware checks admin user ID before allowing
/admin/*routes - Server-Side Validation: All mutations verify admin user ID in server actions
- Upload Security: UploadThing validates admin before allowing file uploads
- Public Safety: Public users only see active bots (down bots hidden)
The app uses TanStack Query for automatic cache invalidation:
- Create Bot: Invalidates admin list, public limited, and public infinite queries
- Update Bot: Invalidates admin list, public queries, and specific bot query
- Delete Bot: Invalidates admin list and all public bot queries
- Toggle Status: Invalidates all bot queries to reflect status changes
This ensures the dashboard and public pages stay in sync automatically!
- Push your code to GitHub
- Import project on Vercel
- Add environment variables:
DATABASE_URLNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEYADMIN_USER_IDNEXT_PUBLIC_ADMIN_USER_IDUPLOADTHING_SECRETUPLOADTHING_APP_ID
- Deploy!
bun run build
bun run startbun dev # Start development server
bun build # Build for production
bun start # Start production server
bun lint # Run ESLint
bun drizzle-kit generate # Generate Drizzle migrations
bun drizzle-kit push # Push schema to databaseContributions are welcome! Please read AGENTS.md for coding standards.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing) - Open a Pull Request
- Component Organization
- Data Fetching
- UI Components
- Authentication
- Forms & Validation- Internationalization
- Motion & Animations
- Pagination
MIT License - feel free to use for your projects!
- Next.js - React framework
- shadcn/ui - UI components
- TanStack Query - Data fetching
- Drizzle ORM - Type-safe ORM
- Neon - Serverless Postgres
- Clerk - Authentication
- UploadThing - File uploads
- Lucide - Icons
- Tailwind CSS - Styling
- motion - Animations
- next-intl - Internationalization
Built with β€οΈ for the Telegram bot community

