{"id":32848459,"url":"https://github.com/mojoschuck/mojo","last_synced_at":"2026-04-13T19:31:43.909Z","repository":{"id":322878593,"uuid":"1079726955","full_name":"MoJoSchuck/mojo","owner":"MoJoSchuck","description":"Social feed built with Next.js App Router, Prisma + Postgres, Clerk auth, and shadcn/ui.","archived":false,"fork":false,"pushed_at":"2025-11-06T19:51:59.000Z","size":488,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-11-06T21:23:06.251Z","etag":null,"topics":["clerk","nextjs","postgres","prisma","shadcn","social-app","tailwindcss","vercel"],"latest_commit_sha":null,"homepage":"https://mojo-psi-one.vercel.app","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/MoJoSchuck.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-20T09:40:28.000Z","updated_at":"2025-11-06T19:52:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/MoJoSchuck/mojo","commit_stats":null,"previous_names":["mojoschuck/mojo"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/MoJoSchuck/mojo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MoJoSchuck%2Fmojo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MoJoSchuck%2Fmojo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MoJoSchuck%2Fmojo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MoJoSchuck%2Fmojo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MoJoSchuck","download_url":"https://codeload.github.com/MoJoSchuck/mojo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MoJoSchuck%2Fmojo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":283333707,"owners_count":26818628,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-11-08T02:00:06.281Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clerk","nextjs","postgres","prisma","shadcn","social-app","tailwindcss","vercel"],"created_at":"2025-11-08T10:00:25.431Z","updated_at":"2025-11-08T10:01:33.288Z","avatar_url":"https://github.com/MoJoSchuck.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# mojo\n\nA modern social media app built with **Next.js App Router**, **Clerk auth**, **Prisma + PostgreSQL**, and **shadcn/ui**.  \nCreate posts (with images), like, comment, follow users, and receive notifications — with real-time updates and a responsive UI.\n\n\u003cimg width=\"1262\" height=\"681\" alt=\"Bildschirmfoto 2025-11-06 um 16 17 27\" src=\"https://github.com/user-attachments/assets/f4906e51-32fe-4c5d-a781-719744fdd0ed\" /\u003e\n\n---\n\n## ✨ Features\n\n- 🔐 **Auth** with Clerk (sign in/out, server-side auth, user sync to DB)\n- 📝 **Posts:** create text/image posts, list feed, delete own posts\n- 💬 **Social:** like posts (optimistic UI), comment (with notifications), follow/unfollow\n- 🔔 **Notifications:** like/comment/follow events, unread marking\n- 👤 **Profile:** dynamic route `/profile/[username]` with posts, likes tabs, and edit profile\n- 🧭 **Who to follow:** suggested users panel\n- 🖼️ **Image uploads** via UploadThing\n- 📱 **Responsive layout** with Navbar/Sidebar and mobile menu\n- 🌗 **Dark/light theme** with next-themes\n\n---\n\n## 🧠 Tech Stack\n\n- **Framework:** Next.js 14 (App Router, Server Components, Server Actions)\n- **Auth:** Clerk (`@clerk/nextjs`)\n- **Database:** PostgreSQL + Prisma ORM\n- **UI:** Tailwind CSS + shadcn/ui (Radix primitives)\n- **Uploads:** UploadThing\n- **Utilities:** date-fns, lucide-react, react-hot-toast\n\n---\n\n## 📁 Project Structure\n\n```bash\nsrc/\n├── app/\n│   ├── layout.tsx                # Root layout, ClerkProvider, ThemeProvider, Navbar, Sidebar\n│   ├── page.tsx                  # Home feed (syncs user, lists posts, shows who to follow)\n│   ├── notifications/page.tsx\n│   ├── profile/[username]/page.tsx\n│   └── api/uploadthing/          # Upload route handler \u0026 core\n├── actions/                      # Server actions (posts, users, profile, notifications)\n├── components/                   # UI components (PostCard, CreatePost, Sidebar, Navbar, etc.)\n├── lib/                          # Prisma client, utils\n├── middleware.ts                 # Clerk middleware with recommended matcher\n└── prisma/\n    └── schema.prisma             # User, Post, Comment, Like, Follow, Notification\n```\n\n---\n\n## 🧩 Data Model (Prisma)\n\n- **User:** profile info and relations (posts, comments, likes, follows, notifications)\n- **Post:** content, image, author, comments, likes\n- **Comment:** content, author, post\n- **Like:** composite (userId, postId)\n- **Follow:** composite PK (followerId, followingId)\n- **Notification:** enum type `LIKE | COMMENT | FOLLOW`; optional post/comment links\n\n---\n\n## 🧱 Notable Implementation Details\n\n- **Server actions**\n  - `post.action.ts`: createPost, getPosts, toggleLike (with notification), createComment (with notification), deletePost\n  - `user.action.ts`: syncUser (syncs Clerk user image/name/email to DB), getUserByClerkId, getDbUserId, getRandomUsers, toggleFollow (with notification)\n  - `profile.action.ts`: getProfileByUsername, getUserPosts, getUserLikedPosts, updateProfile, isFollowing\n  - `notification.action.ts`: getNotifications, markNotificationsAsRead\n\n- **Avatars**\n  - ✅ Uses `object-cover object-center` for proper stretching\n  - ✅ Prefers Clerk image URL (`user.imageUrl`) if available, else falls back to DB image\n\n- **Caching / Revalidation**\n  - Calls `revalidatePath(\"/\")` after mutations and user syncs\n\n- **Middleware**\n  - Clerk middleware configured with App Router matcher in `src/middleware.ts`\n  - Dynamic exports with `% dynamic = \"force-dynamic\"` to ensure auth context is available server-side\n\n- **Mobile Navbar**\n  - Profile links to `/profile/[username]`, derived from Clerk user (fallback to email local-part)\n\n---\n\n## 🚀 Getting Started\n\n### 1. Prerequisites\n\n- Node.js 18+\n- PostgreSQL database (local or hosted)\n- Clerk account (Publishable + Secret Key)\n\n### 2. Environment Variables\n\nCreate a `.env` file in the project root with:\n\n```env\n# Database\nDATABASE_URL=\"postgresql://USER:PASSWORD@HOST:PORT/DB?schema=public\"\n\n# Clerk\nNEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=\"pk_...\"\nCLERK_SECRET_KEY=\"sk_...\"\n\n# UploadThing\nUPLOADTHING_SECRET=\"...\"\nUPLOADTHING_APP_ID=\"...\"\n```\n\n## 🧱 3. Install \u0026 Setup\n\n```bash\nnpm install\nnpx prisma generate\nnpx prisma migrate dev\n```\n\n## 🧩 4. Run Dev Server\n\n```bash\nnpm run dev\n```\n\nThen open: http://localhost:3000\n\n## ☁️ Deployment\n\n- Use your own server or deploy on Vercel (recommended)\n- Ensure your Prisma schema is migrated on your production DB\n- Set environment variables in your hosting platform\n- Deploy as a standard Next.js App Router project\n\n## Project URL\n\n[Live Demo](https://mojo-psi-one.vercel.app)\n\n## 📜 License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmojoschuck%2Fmojo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmojoschuck%2Fmojo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmojoschuck%2Fmojo/lists"}