diff --git a/apps/web/src/components/shared/LeaveTeamDialog.tsx b/apps/web/src/components/shared/LeaveTeamDialog.tsx
index dcdccc4..8fd6579 100644
--- a/apps/web/src/components/shared/LeaveTeamDialog.tsx
+++ b/apps/web/src/components/shared/LeaveTeamDialog.tsx
@@ -12,9 +12,13 @@ import {
} from "@/components/ui/alert-dialog";
import { DropdownMenuItem } from "../ui/dropdown-menu";
import { UserX } from "lucide-react";
-import { leaveTeamMutationClient as _unusedForNowleaveTeamMutationClientleaveTeamMutationClient } from "@/lib/queries";
+import { leaveTeamMutationClient as _unusedForNowleaveTeamMutationClientleaveTeamMutationClient } from "@/lib/functions/queries";
import { useMutation as _unusedForNowuseMutation } from "@tanstack/react-query";
-
+/**
+ * Dialog component that allows a user to leave a team. It prompts the user for confirmation before proceeding with the action. If the team is private, it warns the user that they will need a new invitation to rejoin. If the team is public, it informs the user that they can rejoin later but will lose access to team data.
+ * @param param
+ * @returns
+ */
export function LeaveTeamDialog({
teamId: _unusedForNowTeamId,
teamName,
diff --git a/apps/web/src/components/shared/Navbar/UserButton.tsx b/apps/web/src/components/shared/Navbar/UserButton.tsx
index 0373ed7..d599bd9 100644
--- a/apps/web/src/components/shared/Navbar/UserButton.tsx
+++ b/apps/web/src/components/shared/Navbar/UserButton.tsx
@@ -13,9 +13,12 @@ import {
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { useQuery } from "@tanstack/react-query";
-import { getUserQueryClient, getUserTeamsQueryClient } from "@/lib/queries";
+import {
+ getUserQueryClient,
+ getUserTeamsQueryClient,
+} from "@/lib/functions/queries";
import { Skeleton } from "@/components/ui/skeleton";
-import { getInitials } from "@/lib/utils";
+import { getInitials } from "@/lib/functions/utils";
import { Plus, UserPlus } from "lucide-react";
import { Link } from "@tanstack/react-router";
import { authClient } from "@/lib/auth-client";
diff --git a/apps/web/src/components/shared/Navbar/navbar.tsx b/apps/web/src/components/shared/Navbar/navbar.tsx
index 0b6bcd1..0c8a1d2 100644
--- a/apps/web/src/components/shared/Navbar/navbar.tsx
+++ b/apps/web/src/components/shared/Navbar/navbar.tsx
@@ -6,7 +6,7 @@ import {
NavigationMenuItem,
NavigationMenuList,
} from "@/components/ui/navigation-menu";
-import { shouldShowNavbar } from "@/lib/utils";
+import { shouldShowNavbar } from "@/lib/functions/utils";
import { useLocation } from "@tanstack/react-router";
import { SignedIn, SignedOut } from "@daveyplate/better-auth-ui";
import { Button } from "@/components/ui/button";
diff --git a/apps/web/src/components/ui/alert-dialog.tsx b/apps/web/src/components/ui/alert-dialog.tsx
index 9cc7ed9..78756bd 100644
--- a/apps/web/src/components/ui/alert-dialog.tsx
+++ b/apps/web/src/components/ui/alert-dialog.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
import { buttonVariants } from "@/components/ui/button";
function AlertDialog({
diff --git a/apps/web/src/components/ui/alert.tsx b/apps/web/src/components/ui/alert.tsx
index c636967..c9af786 100644
--- a/apps/web/src/components/ui/alert.tsx
+++ b/apps/web/src/components/ui/alert.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
const alertVariants = cva(
"relative w-full rounded-lg border px-4 py-3 text-sm grid has-[>svg]:grid-cols-[calc(var(--spacing)*4)_1fr] grid-cols-[0_1fr] has-[>svg]:gap-x-3 gap-y-0.5 items-start [&>svg]:size-4 [&>svg]:translate-y-0.5 [&>svg]:text-current",
diff --git a/apps/web/src/components/ui/avatar.tsx b/apps/web/src/components/ui/avatar.tsx
index 3f19c82..56ea2a7 100644
--- a/apps/web/src/components/ui/avatar.tsx
+++ b/apps/web/src/components/ui/avatar.tsx
@@ -3,7 +3,7 @@
import * as React from "react";
import * as AvatarPrimitive from "@radix-ui/react-avatar";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Avatar({
className,
diff --git a/apps/web/src/components/ui/breadcrumb.tsx b/apps/web/src/components/ui/breadcrumb.tsx
index 9392996..a5bf33e 100644
--- a/apps/web/src/components/ui/breadcrumb.tsx
+++ b/apps/web/src/components/ui/breadcrumb.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { ChevronRight, MoreHorizontal } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Breadcrumb({ ...props }: React.ComponentProps<"nav">) {
return ;
diff --git a/apps/web/src/components/ui/button.tsx b/apps/web/src/components/ui/button.tsx
index fde652b..5a20451 100644
--- a/apps/web/src/components/ui/button.tsx
+++ b/apps/web/src/components/ui/button.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-all disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
diff --git a/apps/web/src/components/ui/dropdown-menu.tsx b/apps/web/src/components/ui/dropdown-menu.tsx
index f196abc..0ee731e 100644
--- a/apps/web/src/components/ui/dropdown-menu.tsx
+++ b/apps/web/src/components/ui/dropdown-menu.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function DropdownMenu({
...props
diff --git a/apps/web/src/components/ui/input.tsx b/apps/web/src/components/ui/input.tsx
index c444028..744d762 100644
--- a/apps/web/src/components/ui/input.tsx
+++ b/apps/web/src/components/ui/input.tsx
@@ -1,6 +1,6 @@
import * as React from "react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Input({ className, type, ...props }: React.ComponentProps<"input">) {
return (
diff --git a/apps/web/src/components/ui/menubar.tsx b/apps/web/src/components/ui/menubar.tsx
index 000ac19..623bb05 100644
--- a/apps/web/src/components/ui/menubar.tsx
+++ b/apps/web/src/components/ui/menubar.tsx
@@ -2,7 +2,7 @@ import * as React from "react";
import * as MenubarPrimitive from "@radix-ui/react-menubar";
import { CheckIcon, ChevronRightIcon, CircleIcon } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Menubar({
className,
diff --git a/apps/web/src/components/ui/navigation-menu.tsx b/apps/web/src/components/ui/navigation-menu.tsx
index 4b2529d..5faca7a 100644
--- a/apps/web/src/components/ui/navigation-menu.tsx
+++ b/apps/web/src/components/ui/navigation-menu.tsx
@@ -3,7 +3,7 @@ import * as NavigationMenuPrimitive from "@radix-ui/react-navigation-menu";
import { cva } from "class-variance-authority";
import { ChevronDownIcon } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function NavigationMenu({
className,
diff --git a/apps/web/src/components/ui/scroll-area.tsx b/apps/web/src/components/ui/scroll-area.tsx
index aa845a8..0d696a2 100644
--- a/apps/web/src/components/ui/scroll-area.tsx
+++ b/apps/web/src/components/ui/scroll-area.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function ScrollArea({
className,
diff --git a/apps/web/src/components/ui/separator.tsx b/apps/web/src/components/ui/separator.tsx
index 4df6a8f..a0c1256 100644
--- a/apps/web/src/components/ui/separator.tsx
+++ b/apps/web/src/components/ui/separator.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as SeparatorPrimitive from "@radix-ui/react-separator";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Separator({
className,
diff --git a/apps/web/src/components/ui/sheet.tsx b/apps/web/src/components/ui/sheet.tsx
index ee592c7..33f8cb0 100644
--- a/apps/web/src/components/ui/sheet.tsx
+++ b/apps/web/src/components/ui/sheet.tsx
@@ -4,7 +4,7 @@ import * as React from "react";
import * as SheetPrimitive from "@radix-ui/react-dialog";
import { XIcon } from "lucide-react";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Sheet({ ...props }: React.ComponentProps) {
return ;
diff --git a/apps/web/src/components/ui/sidebar.tsx b/apps/web/src/components/ui/sidebar.tsx
index ffe75e1..ad8601d 100644
--- a/apps/web/src/components/ui/sidebar.tsx
+++ b/apps/web/src/components/ui/sidebar.tsx
@@ -6,7 +6,7 @@ import { cva, type VariantProps } from "class-variance-authority";
import { PanelLeftIcon } from "lucide-react";
import { useIsMobile } from "@/hooks/use-mobile";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Separator } from "@/components/ui/separator";
diff --git a/apps/web/src/components/ui/skeleton.tsx b/apps/web/src/components/ui/skeleton.tsx
index eded6ce..353f6c0 100644
--- a/apps/web/src/components/ui/skeleton.tsx
+++ b/apps/web/src/components/ui/skeleton.tsx
@@ -1,4 +1,4 @@
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
return (
diff --git a/apps/web/src/components/ui/switch.tsx b/apps/web/src/components/ui/switch.tsx
index 39ab03e..a72c987 100644
--- a/apps/web/src/components/ui/switch.tsx
+++ b/apps/web/src/components/ui/switch.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as SwitchPrimitive from "@radix-ui/react-switch";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function Switch({
className,
diff --git a/apps/web/src/components/ui/tooltip.tsx b/apps/web/src/components/ui/tooltip.tsx
index f018f6b..057d0f3 100644
--- a/apps/web/src/components/ui/tooltip.tsx
+++ b/apps/web/src/components/ui/tooltip.tsx
@@ -1,7 +1,7 @@
import * as React from "react";
import * as TooltipPrimitive from "@radix-ui/react-tooltip";
-import { cn } from "@/lib/utils";
+import { cn } from "@/lib/functions/utils";
function TooltipProvider({
delayDuration = 0,
diff --git a/apps/web/src/lib/functions/auth.ts b/apps/web/src/lib/functions/auth.ts
index 71c242c..713c69d 100644
--- a/apps/web/src/lib/functions/auth.ts
+++ b/apps/web/src/lib/functions/auth.ts
@@ -2,24 +2,47 @@ import { authClient } from "../auth-client";
import { PUBLIC_ROUTES } from "shared/constants";
import type { RouterContext } from "../types";
import { redirect } from "@tanstack/react-router";
-
+/**
+ * Checks if a given pathname is a public route.
+ * @param pathname - The pathname to check
+ * @returns True if the pathname is a public route, false otherwise
+ */
export function isPublicRoute(pathname: string) {
return PUBLIC_ROUTES.includes(pathname);
}
+/**
+ * Checks if a given pathname is a protected route (i.e., not a public route).
+ * @param pathname - The pathname to check
+ * @returns True if the pathname is a protected route, false otherwise
+ */
export function isProtectedRoute(pathname: string) {
return !isPublicRoute(pathname);
}
+/**
+ * Retrieves the current user session from the authentication client.
+ * @returns The session data if a user is authenticated, or null if not authenticated
+ */
export async function getSession() {
return authClient.getSession();
}
+/**
+ * Signs out the current user.
+ * @returns An object containing the sign-out data and any error encountered
+ */
export async function signOut() {
const { data, error } = await authClient.signOut();
return { data, error };
}
+/**
+ * Redirects the user to a specified path if they are already signed in.
+ * @param ctx - The router context containing authentication information
+ * @param to - The path to redirect to if the user is signed in (default is "/")
+ * @throws A redirect to the specified path if the user is authenticated
+ */
export function redirectIfSignedIn(ctx: RouterContext, to: string = "/") {
if (ctx.auth?.data) {
throw redirect({
diff --git a/apps/web/src/lib/queries.ts b/apps/web/src/lib/functions/queries.ts
similarity index 60%
rename from apps/web/src/lib/queries.ts
rename to apps/web/src/lib/functions/queries.ts
index 6fb0c68..f0502e7 100644
--- a/apps/web/src/lib/queries.ts
+++ b/apps/web/src/lib/functions/queries.ts
@@ -1,7 +1,11 @@
import { queryOptions, mutationOptions } from "@tanstack/react-query";
-import { apiClient } from "./api-client";
-import { authClient } from "./auth-client";
+import { apiClient } from "../api-client";
+import { authClient } from "../auth-client";
+/**
+ * A query client for pinging the server to check its health status.
+ * @returns An object containing the query key and query function for pinging the server.
+ */
export const pingServerQueryClient = queryOptions({
queryKey: ["ping"],
queryFn: async () => {
@@ -16,6 +20,10 @@ export const pingServerQueryClient = queryOptions({
},
});
+/**
+ * A query client for retrieving the current authenticated user's information.
+ * @returns An object containing the query key and query function for fetching the user data.
+ */
export const getUserQueryClient = queryOptions({
queryKey: ["user"],
queryFn: async () => {
@@ -28,6 +36,10 @@ export const getUserQueryClient = queryOptions({
},
});
+/**
+ * A query client for fetching the teams that the current user belongs to.
+ * @returns An object containing the query key and query function for retrieving the user's teams.
+ */
export const getUserTeamsQueryClient = queryOptions({
queryKey: ["user", "teams"],
queryFn: async () => {
@@ -39,8 +51,12 @@ export const getUserTeamsQueryClient = queryOptions({
throw new Error("Something went wrong");
},
});
-
-export const joinTeamMutationclient = (inviteCode: string) =>
+/**
+ * A mutation client for joining a team using an invite code.
+ * @param inviteCode - The invite code for the team to join
+ * @returns An object containing the mutation key and mutation function for joining a team.
+ */
+export const joinTeamMutationClient = (inviteCode: string) =>
mutationOptions({
mutationKey: ["team", inviteCode, "join"],
mutationFn: async () => {
@@ -59,6 +75,12 @@ export const joinTeamMutationclient = (inviteCode: string) =>
},
});
+/**
+ * A mutation client for leaving a team.
+ * @param teamId - The ID of the team to leave
+ * @param userId - The ID of the user leaving the team
+ * @returns An object containing the mutation key and mutation function for leaving a team.
+ */
export const leaveTeamMutationClient = (teamId: string, userId: string) =>
mutationOptions({
mutationKey: ["team", teamId, userId, "remove"],
diff --git a/apps/web/src/lib/utils.ts b/apps/web/src/lib/functions/utils.ts
similarity index 100%
rename from apps/web/src/lib/utils.ts
rename to apps/web/src/lib/functions/utils.ts
diff --git a/apps/web/src/routes/index.tsx b/apps/web/src/routes/index.tsx
index ad3b8b5..ad53925 100644
--- a/apps/web/src/routes/index.tsx
+++ b/apps/web/src/routes/index.tsx
@@ -2,7 +2,7 @@ import { createFileRoute } from "@tanstack/react-router";
import { APP_NAME } from "shared/constants";
import { Button } from "@/components/ui/button";
import { toast } from "sonner";
-import { pingServerQueryClient } from "@/lib/queries";
+import { pingServerQueryClient } from "@/lib/functions/queries";
import { useQuery } from "@tanstack/react-query";
import { SignedIn, SignedOut } from "@daveyplate/better-auth-ui";
import { Link } from "@tanstack/react-router";