From 6fccb7651065f3244b0d7c7f57c145c2ddfa483b Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Mon, 26 Jan 2026 06:37:04 +1100 Subject: [PATCH 1/2] Fix avatar --- components/core/user-avatar.tsx | 6 ++---- components/core/user-menu.tsx | 2 +- components/project/shared/creator-details.tsx | 2 +- components/project/shared/user-badge.tsx | 6 ++++-- components/settings/team-settings.tsx | 1 - drizzle/types.ts | 6 +++++- hooks/use-tasks.tsx | 2 ++ trpc/routers/tasks.ts | 4 ++++ 8 files changed, 19 insertions(+), 10 deletions(-) diff --git a/components/core/user-avatar.tsx b/components/core/user-avatar.tsx index 3fc3a2d..7f1bbb7 100644 --- a/components/core/user-avatar.tsx +++ b/components/core/user-avatar.tsx @@ -5,8 +5,7 @@ type UserAvatarProps = { user?: { firstName?: string | null; name?: string | null; - email?: string | null; - id?: string | null; + id: string; } | null; className?: string; compact?: boolean; @@ -21,8 +20,7 @@ export const UserAvatar = ({ className, compact = false, }: UserAvatarProps) => { - const seed = - user?.id || user?.email || user?.firstName || user?.name || "default"; + const seed = user?.id || "default"; const fallbackText = user?.firstName?.[0] || user?.name?.[0] || "U"; return ( diff --git a/components/core/user-menu.tsx b/components/core/user-menu.tsx index 9190ffe..2c39d18 100644 --- a/components/core/user-menu.tsx +++ b/components/core/user-menu.tsx @@ -40,7 +40,7 @@ export function UserMenu() { diff --git a/components/project/shared/creator-details.tsx b/components/project/shared/creator-details.tsx index 31a76eb..0b35f81 100644 --- a/components/project/shared/creator-details.tsx +++ b/components/project/shared/creator-details.tsx @@ -5,7 +5,7 @@ export const CreatorDetails = ({ user, updatedAt, }: { - user: Pick; + user: Pick; updatedAt: Date; }) => { return ( diff --git a/components/project/shared/user-badge.tsx b/components/project/shared/user-badge.tsx index 37d78cd..69a3510 100644 --- a/components/project/shared/user-badge.tsx +++ b/components/project/shared/user-badge.tsx @@ -8,13 +8,15 @@ export function UserBadge({ imageOnly = false, }: { className?: string; - user: Pick; + user: Pick & { email?: string }; imageOnly?: boolean; }) { return (
- {!imageOnly ?

{user?.firstName}

: null} + {!imageOnly ? ( +

{user?.firstName || user?.email}

+ ) : null}
); } diff --git a/components/settings/team-settings.tsx b/components/settings/team-settings.tsx index 8352fc1..aeb7e9a 100644 --- a/components/settings/team-settings.tsx +++ b/components/settings/team-settings.tsx @@ -193,7 +193,6 @@ export function TeamSettings() { id: member.user.id, firstName: member.user.firstName, name: member.user.name, - email: member.user.email, }} />
diff --git a/drizzle/types.ts b/drizzle/types.ts index d2f7980..be46678 100644 --- a/drizzle/types.ts +++ b/drizzle/types.ts @@ -48,11 +48,15 @@ export type ProjectWithCreator = Project & { creator: User }; export type TaskWithDetails = Task & { creator: { + id: string; firstName: string | null; + email: string; image: string | null; }; assignee: { + id: string; firstName: string | null; + email: string; image: string | null; } | null; }; @@ -62,7 +66,7 @@ export type TaskListWithTasks = TaskList & { }; export type BlobWithCreater = Blob & { - creator: Pick; + creator: Pick; }; export type EventWithCreator = CalendarEvent & { diff --git a/hooks/use-tasks.tsx b/hooks/use-tasks.tsx index c626e5e..a9e42db 100644 --- a/hooks/use-tasks.tsx +++ b/hooks/use-tasks.tsx @@ -86,7 +86,9 @@ export function TasksProvider({ position: 0, assignedToUser: null, creator: { + id: session?.user?.id || "", firstName: session?.user?.name || null, + email: session?.user?.email || "", image: session?.user?.image || null, }, assignee: null, diff --git a/trpc/routers/tasks.ts b/trpc/routers/tasks.ts index 07c6c7f..2e2b922 100644 --- a/trpc/routers/tasks.ts +++ b/trpc/routers/tasks.ts @@ -240,13 +240,17 @@ export const tasksRouter = createTRPCRouter({ with: { creator: { columns: { + id: true, firstName: true, + email: true, image: true, }, }, assignee: { columns: { + id: true, firstName: true, + email: true, image: true, }, }, From 8c8472333f364b7a49272855f76d753e9864ca13 Mon Sep 17 00:00:00 2001 From: Arjun Komath Date: Mon, 26 Jan 2026 15:50:23 +1100 Subject: [PATCH 2/2] Self hosting fixes --- .env.example | 3 +++ README.md | 18 +++++++++++++++++- app/layout.tsx | 2 -- app/page.tsx | 19 ++++++++++++++++++- lib/config.ts | 4 ++++ package.json | 2 -- 6 files changed, 42 insertions(+), 6 deletions(-) diff --git a/.env.example b/.env.example index a0f48f8..9753add 100644 --- a/.env.example +++ b/.env.example @@ -11,6 +11,9 @@ BETTER_AUTH_URL=http://localhost:3000 # Set to "true" to disable new user signups (existing users can still sign in) # DISABLE_SIGNUPS=true +# Set to "true" for self-hosted instances (skips marketing landing page) +# SELF_HOSTED=true + # Email (SMTP) SMTP_HOST=smtp.example.com SMTP_PORT=587 diff --git a/README.md b/README.md index 09146a8..e4f1352 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,23 @@ Manage is an open-source project management platform. With its intuitive interfa # See .env.example for all available environment variables ``` -## Deployment +## Self-Hosting + +Deploy your own instance of Manage with one click: + +[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/deploy/manage) + +### Manual Deployment + +Manage can be deployed on any platform that supports Node.js/Bun. You'll need: + +- PostgreSQL database +- S3-compatible storage (optional, for file uploads) +- SMTP server (for email notifications) + +See `.env.example` for all required environment variables. + +## Hosting Railway diff --git a/app/layout.tsx b/app/layout.tsx index f5fe66a..667e831 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,4 +1,3 @@ -import { Analytics } from "@vercel/analytics/next"; import { ThemeProvider } from "@/components/core/theme-provider"; import { Toaster } from "@/components/ui/sonner"; import { SITE_METADATA } from "@/data/marketing"; @@ -315,7 +314,6 @@ export default function RootLayout({ {children} - ); diff --git a/app/page.tsx b/app/page.tsx index ccfeee0..8272ffb 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -5,7 +5,7 @@ import { ClientRedirect } from "@/components/core/client-redirect"; import { Footer } from "@/components/layout/footer"; import { Header } from "@/components/layout/header"; import { auth } from "@/lib/auth"; -import { isSignupDisabled } from "@/lib/config"; +import { isSelfHosted, isSignupDisabled } from "@/lib/config"; export default async function Home() { const session = await auth.api.getSession({ @@ -15,6 +15,10 @@ export default async function Home() { return ; } + if (isSelfHosted()) { + return ; + } + const signupsDisabled = isSignupDisabled(); return ( @@ -289,6 +293,19 @@ export default async function Home() { growing community. No vendor lock-in, no hidden costs.

+ + + + + Deploy on Railway +