diff --git a/.env.sample b/.env.sample index 0d441c8..e208669 100644 --- a/.env.sample +++ b/.env.sample @@ -38,3 +38,7 @@ NEXT_PUBLIC_POSTHOG_HOST=replace_me # used to show breakpoint overlay in development NEXT_PUBLIC_IS_LOCAL=true + +# Tell if it's development or not +## .env.development, add: NODE_ENV=development +## .env.production, add: NODE_ENV=production \ No newline at end of file diff --git a/src/app-config.tsx b/src/app-config.tsx index a426bef..4fdf8c2 100644 --- a/src/app-config.tsx +++ b/src/app-config.tsx @@ -1,21 +1,22 @@ export const appConfig: { - mode: "comingSoon" | "maintenance" | "live"; + mode: "comingSoon" | "maintenance" | "live" } = { - mode: "live", -}; + mode: "live", +} -export const protectedRoutes = ["/purchases", "/dashboard"]; -export const applicationName = "Group Finder"; -export const companyName = "Groupie, LLC"; +export const protectedRoutes = ["/purchases", "/dashboard"] +export const applicationName = "Group Finder" +export const companyName = "Groupie, LLC" +export const siteName = "GroupFinder.com" -export const MAX_UPLOAD_IMAGE_SIZE_IN_MB = 5; -export const MAX_UPLOAD_IMAGE_SIZE = 1024 * 1024 * MAX_UPLOAD_IMAGE_SIZE_IN_MB; +export const MAX_UPLOAD_IMAGE_SIZE_IN_MB = 5 +export const MAX_UPLOAD_IMAGE_SIZE = 1024 * 1024 * MAX_UPLOAD_IMAGE_SIZE_IN_MB -export const TOKEN_LENGTH = 32; -export const TOKEN_TTL = 1000 * 60 * 5; // 5 min -export const VERIFY_EMAIL_TTL = 1000 * 60 * 60 * 24 * 7; // 7 days +export const TOKEN_LENGTH = 32 +export const TOKEN_TTL = 1000 * 60 * 5 // 5 min +export const VERIFY_EMAIL_TTL = 1000 * 60 * 60 * 24 * 7 // 7 days -export const MAX_GROUP_LIMIT = 10; -export const MAX_GROUP_PREMIUM_LIMIT = 50; +export const MAX_GROUP_LIMIT = 10 +export const MAX_GROUP_PREMIUM_LIMIT = 50 -export const afterLoginUrl = "/dashboard"; +export const afterLoginUrl = "/dashboard" diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 227d33a..8e596db 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,96 +1,99 @@ -import "@/app/globals.css"; -import "fumadocs-ui/style.css"; -import type { Metadata } from "next"; -import NextTopLoader from "nextjs-toploader"; -import { Toaster } from "@/components/ui/toaster"; -import { cn } from "@/lib/utils"; -import { ReactNode, Suspense } from "react"; -import { Providers } from "@/providers/providers"; -import { Footer } from "@/components/footer"; -import { applicationName, appConfig } from "@/app-config"; -import PostHogPageView from "@/components/posthog-page-view"; -import { ComingSoonFooter } from "@/app/(coming-soon)/footer"; -import { Header } from "@/app/_header/header"; +import "@/app/globals.css" +import "fumadocs-ui/style.css" +import type { Metadata } from "next" +import NextTopLoader from "nextjs-toploader" +import { Toaster } from "@/components/ui/toaster" +import { cn } from "@/lib/utils" +import { ReactNode, Suspense } from "react" +import { Providers } from "@/providers/providers" +import { Footer } from "@/components/footer" +import { applicationName, appConfig } from "@/app-config" +import PostHogPageView from "@/components/posthog-page-view" +import { ComingSoonFooter } from "@/app/(coming-soon)/footer" +import { Header } from "@/app/_header/header" -import { Archivo } from "next/font/google"; -import { Libre_Franklin } from "next/font/google"; -import { BreakpointOverlay } from "@/components/breakpoint-overlay"; +import { Archivo } from "next/font/google" +import { Libre_Franklin } from "next/font/google" +import { BreakpointOverlay } from "@/components/breakpoint-overlay" const archivo = Archivo({ - subsets: ["latin"], - display: "swap", - variable: "--font-archivo", -}); + subsets: ["latin"], + display: "swap", + variable: "--font-archivo", +}) const libre_franklin = Libre_Franklin({ - subsets: ["latin"], - display: "swap", - variable: "--font-libre_franklin", -}); + subsets: ["latin"], + display: "swap", + variable: "--font-libre_franklin", +}) -const { mode } = appConfig; +const { mode } = appConfig export const metadata: Metadata = { - title: applicationName, - icons: [ - { rel: "icon", type: "image/png", sizes: "48x48", url: "/favicon.ico" }, - ], - keywords: - "next.js, starter kit, saas, ecommerce, digital products, saas code kit, indie hacking, indie hacker kit, micro saas, entrepreneurship, Code Starter Kit, SaaS Product Launch, Code Documentation Tutorial, Beginner Coding Kit, Start-up SaaS Kit, Coding Guides and Resources, Video Tutorials for Coding, Beginner SaaS Guide, Launch your First SaaS, Step-by-step Coding Kit, SaaS Launch Kit, Software as a Service Starter, Easy Code Launch Kit, Coding Skills for SaaS, Starter Kit for SaaS, Code, Document, Launch, Comprehensive Coding Starter Kit, Master SaaS Product Launch, SaaS Documentation Tutorial, First-Time Coders Kit, SaaS coding course, Initiate SaaS Journey, Seamless SaaS Launch Guide, First SaaS Product Guidance, Bootstrap SaaS Tutorial, Ultimate SaaS Starter Pack, Learning Guide for SaaS, DIY SaaS Kit, Code your SaaS Product, All-in-one Coding Starter Kit", - description: - "The code kit to help you quickly setup an online store and sell your digital assets without a middleman skipping off the top of your profits.", - openGraph: - mode === "comingSoon" - ? { - title: "WDCStarterKit.com", - description: - "I'm building the ultimate next.js starter kit to help you hit the ground runnning on your next saas product.", - url: "https://wdcstarterkit.com", - siteName: "WDC StarterKit", - type: "website", - images: [ - { - url: "https://wdcstarterkit.com/starterkitcard.png", - secureUrl: "https://wdcstarterkit.com/starterkitcard.png", - width: 800, - height: 418, - alt: "The WDC StarterKit social media card image", - }, - ], - } - : undefined, -}; + title: + process.env.NODE_ENV === "development" + ? `DEV - ${applicationName} ` + : applicationName, + icons: [ + { rel: "icon", type: "image/png", sizes: "48x48", url: "/favicon.ico" }, + ], + keywords: + "next.js, starter kit, saas, ecommerce, digital products, saas code kit, indie hacking, indie hacker kit, micro saas, entrepreneurship, Code Starter Kit, SaaS Product Launch, Code Documentation Tutorial, Beginner Coding Kit, Start-up SaaS Kit, Coding Guides and Resources, Video Tutorials for Coding, Beginner SaaS Guide, Launch your First SaaS, Step-by-step Coding Kit, SaaS Launch Kit, Software as a Service Starter, Easy Code Launch Kit, Coding Skills for SaaS, Starter Kit for SaaS, Code, Document, Launch, Comprehensive Coding Starter Kit, Master SaaS Product Launch, SaaS Documentation Tutorial, First-Time Coders Kit, SaaS coding course, Initiate SaaS Journey, Seamless SaaS Launch Guide, First SaaS Product Guidance, Bootstrap SaaS Tutorial, Ultimate SaaS Starter Pack, Learning Guide for SaaS, DIY SaaS Kit, Code your SaaS Product, All-in-one Coding Starter Kit", + description: + "The code kit to help you quickly setup an online store and sell your digital assets without a middleman skipping off the top of your profits.", + openGraph: + mode === "comingSoon" + ? { + title: "WDCStarterKit.com", + description: + "I'm building the ultimate next.js starter kit to help you hit the ground runnning on your next saas product.", + url: "https://wdcstarterkit.com", + siteName: "WDC StarterKit", + type: "website", + images: [ + { + url: "https://wdcstarterkit.com/starterkitcard.png", + secureUrl: + "https://wdcstarterkit.com/starterkitcard.png", + width: 800, + height: 418, + alt: "The WDC StarterKit social media card image", + }, + ], + } + : undefined, +} export default async function RootLayout({ - children, + children, }: Readonly<{ - children: ReactNode; + children: ReactNode }>) { - return ( - - - - - - - -
- {appConfig.mode === "live" &&
} -
{children}
- {appConfig.mode === "comingSoon" ? ( - - ) : ( -
-
- - - - - ); + return ( + + + + + + + +
+ {appConfig.mode === "live" &&
} +
{children}
+ {appConfig.mode === "comingSoon" ? ( + + ) : ( +
+ )} +
+
+ + + + + ) } diff --git a/src/app/users/[userId]/profile-header.tsx b/src/app/users/[userId]/profile-header.tsx index 76194b6..2e5f25a 100644 --- a/src/app/users/[userId]/profile-header.tsx +++ b/src/app/users/[userId]/profile-header.tsx @@ -1,60 +1,68 @@ -import { Button } from "@/components/ui/button"; -import { getCurrentUser } from "@/lib/session"; -import { headerStyles, pageTitleStyles } from "@/styles/common"; -import { btnIconStyles, btnStyles } from "@/styles/icons"; -import { getUserProfileUseCase } from "@/use-cases/users"; -import { SquareUser } from "lucide-react"; -import Image from "next/image"; -import Link from "next/link"; -import { FollowButton } from "./follow-button"; -import { isFollowingUserUseCase } from "@/use-cases/following"; -import { UnfollowButton } from "./unfollow-button"; -import { cn } from "@/lib/utils"; -import { UserId } from "@/use-cases/types"; +import { Button } from "@/components/ui/button" +import { getCurrentUser } from "@/lib/session" +import { headerStyles, pageTitleStyles } from "@/styles/common" +import { btnIconStyles, btnStyles } from "@/styles/icons" +import { getUserProfileUseCase } from "@/use-cases/users" +import { SquareUser } from "lucide-react" +import Image from "next/image" +import Link from "next/link" +import { FollowButton } from "./follow-button" +import { isFollowingUserUseCase } from "@/use-cases/following" +import { UnfollowButton } from "./unfollow-button" +import { cn } from "@/lib/utils" +import { UserId } from "@/use-cases/types" +import { siteName } from "@/app-config" export async function ProfileHeader({ userId }: { userId: UserId }) { - const user = await getCurrentUser(); - const profile = await getUserProfileUseCase(userId); - const isOwnProfile = user?.id === userId; + const user = await getCurrentUser() + const profile = await getUserProfileUseCase(userId) + const isUnderDevelopment = process.env.NODE_ENV === "development" + const url = isUnderDevelopment + ? "http://localhost:3000" + : `https://${siteName}` + const profileImage = `${url}/api/users/2/images/${profile.imageId}` + const isOwnProfile = user?.id === userId - const isFollowingUser = user - ? await isFollowingUserUseCase(user, userId) - : false; + const isFollowingUser = user + ? await isFollowingUserUseCase(user, userId) + : false - const shouldShowFollowButtons = user && !isOwnProfile; + const shouldShowFollowButtons = user && !isOwnProfile - return ( -
-
-
-
- image of the group + return ( +
+
+
+
+ image of the group +

+ {profile.displayName}{" "} +

+
-

{profile.displayName}

-
+ {shouldShowFollowButtons && + (isFollowingUser ? ( + + ) : ( + + ))} - {shouldShowFollowButtons && - (isFollowingUser ? ( - - ) : ( - - ))} - - {isOwnProfile && ( - - )} -
-
-
- ); + {isOwnProfile && ( + + )} +
+
+
+ ) } diff --git a/src/components/breakpoint-overlay.tsx b/src/components/breakpoint-overlay.tsx index 33e68c9..5bf3fae 100644 --- a/src/components/breakpoint-overlay.tsx +++ b/src/components/breakpoint-overlay.tsx @@ -1,16 +1,20 @@ -"use client"; +"use client" export function BreakpointOverlay() { - if (process.env.NEXT_PUBLIC_IS_LOCAL !== "true") return null; + if ( + process.env.NEXT_PUBLIC_IS_LOCAL !== "true" || + process.env.NODE_ENV === "production" + ) + return null - return ( -
- xs - sm - md - lg - xl - 2xl -
- ); + return ( +
+ xs + sm + md + lg + xl + 2xl +
+ ) }