Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions app/communities/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import React, { useEffect, useMemo } from "react";
import { Community } from "@/types/community";

/**
* Lists communities with infinite scroll, grouped by membership state.
* @returns Communities page with moderation, joined, and discovery sections.
* A page that displays a comprehensive list of all communities.
* Organizes communities into categories: those the user moderates, those they have joined, and others for discovery.
* Implements infinite scrolling for efficient data loading.
* @returns The communities directory page.
*/
const Communities: React.FC = () => {
const { communityStateValue } = useCommunityState();
Expand Down
8 changes: 5 additions & 3 deletions app/community/[communityId]/comments/CommunityClientPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ type CommunityPageProps = {
};

/**
* Client-side community page wiring header, posts feed, and about sidebar.
* @param communityData - Community data fetched on the server.
* @returns Community layout with feed and management panels.
* The client-side entry point for a community's main page.
* Synchronizes server-fetched community data with the global state and renders the community header, post feed, and sidebar.
* Handles permission checks to restrict access to private or restricted communities.
* @param communityData - The initial community data fetched on the server.
* @returns A structured layout containing the community's content and metadata.
*/
const CommunityClientPage: React.FC<CommunityPageProps> = ({
communityData,
Expand Down
10 changes: 6 additions & 4 deletions app/community/[communityId]/comments/[pid]/PostClientPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ type PostPageProps = {
};

/**
* Client page for a single post with voting, deletion, and threaded comments.
* @param communityData - Community context for the post.
* @param postData - Post fetched on the server; may be null if not found.
* @returns Layout with post content on the left and community about panel on the right.
* The client-side page for viewing a single post and its associated comment thread.
* Manages post-specific state including voting, deletion, and comment loading.
* Enforces community-level viewing permissions.
* @param communityData - The community context for the post.
* @param postData - The post data fetched on the server.
* @returns A page layout with the post item and its comments.
*/
const PostPage: React.FC<PostPageProps> = ({ communityData, postData }) => {
const { postStateValue, setPostStateValue } = usePostState();
Expand Down
7 changes: 4 additions & 3 deletions app/community/[communityId]/comments/[pid]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { notFound } from "next/navigation";
import PostClientPage from "./PostClientPage";

/**
* Server component that fetches community and post data for the comments route.
* @param params - Route params containing community and post ids.
* @returns Client comment page or an error/not-found fallback.
* A server-side page component for viewing a single post and its comments.
* Fetches both the community and post data to provide full context for the client page.
* @param params - The dynamic route parameters containing the community ID and post ID.
* @returns The client-side post detail page.
*/
export default async function PostPage({
params,
Expand Down
7 changes: 4 additions & 3 deletions app/community/[communityId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { notFound } from "next/navigation";
import CommunityClientPage from "./comments/CommunityClientPage";

/**
* Server component that loads community data and renders the client view.
* @param params - Route params containing the community id.
* @returns Community client page or a not-found/error fallback.
* A server-side page component that fetches data for a specific community.
* Validates the community ID and handles error states or non-existent communities by showing a 404 page.
* @param params - The dynamic route parameters containing the community ID.
* @returns The client-side community page populated with server-fetched data.
*/
export default async function Page({
params,
Expand Down
8 changes: 5 additions & 3 deletions app/community/[communityId]/submit/SubmitPostClientPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@ type SubmitPostPageProps = {
};

/**
* Client page for creating a new post inside a community.
* @param communityData - Community where the post will be published.
* @returns Post creation form with sidebar about section.
* The client-side page for submitting a new post to a community.
* Enforces authentication and community-specific posting permissions.
* Renders the post creation form and a sidebar with community information.
* @param communityData - The community context for the new post.
* @returns A page containing the post creation form or access restriction messages.
*/
const SubmitPostPage: React.FC<SubmitPostPageProps> = ({ communityData }) => {
const [user] = useAuthState(auth);
Expand Down
7 changes: 4 additions & 3 deletions app/community/[communityId]/submit/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { notFound } from "next/navigation";
import SubmitPostClientPage from "./SubmitPostClientPage";

/**
* Server component that prepares data for the submit-post page of a community.
* @param params - Route params containing the community id.
* @returns Client submit page or an error/not-found fallback.
* A server-side page component for the post submission route.
* Fetches the target community's data to ensure it exists and to provide context for the submission form.
* @param params - The dynamic route parameters containing the community ID.
* @returns The client-side post submission page.
*/
export default async function SubmitPostPage({
params,
Expand Down
7 changes: 4 additions & 3 deletions app/emotion-registry.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import { useServerInsertedHTML } from "next/navigation";
import { useState } from "react";

/**
* Configures Emotion cache for the App Router and injects styles during SSR.
* @param children - React tree that needs Emotion styling support.
* @returns Cache provider that ensures styles render on both server and client.
* A client-side component that manages the Emotion CSS-in-JS cache for the Next.js App Router.
* Ensures that styles generated on the server are correctly hydrated and injected into the document.
* @param children - The component tree that requires Emotion styling.
* @returns A provider that supplies the Emotion cache to its descendants.
*/
export default function EmotionRegistry({
children,
Expand Down
7 changes: 4 additions & 3 deletions app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ export const metadata: Metadata = {
};

/**
* Root layout wiring global providers and metadata for the App Router.
* @param children - Route content to render inside the provider tree.
* @returns HTML scaffold with Providers applied to the body.
* The root layout component for the entire application.
* Defines the base HTML structure, global metadata, and wraps the application in the necessary providers.
* @param children - The content of the current route.
* @returns The top-level HTML structure for the application.
*/
export default function RootLayout({
children,
Expand Down
6 changes: 4 additions & 2 deletions app/not-found.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import Link from "next/link";
import React from "react";

/**
* Fallback page for unknown routes with quick links back to core pages.
* @returns Centered message and navigation buttons.
* The default 404 error page for the application.
* Displayed when a user navigates to a non-existent route.
* Provides helpful links to return to the home page or browse communities.
* @returns A centered error message with navigation options.
*/
const PageNotFound: React.FC = () => {
return (
Expand Down
6 changes: 4 additions & 2 deletions app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@
import { useAuthState } from "react-firebase-hooks/auth";

/**
* Renders the home feed with infinite scrolling posts and a sidebar of recommendations.
* @returns Main content paired with community suggestions and personal shortcuts.
* The main landing page of the application.
* Displays a personalized feed of posts for authenticated users or a generic popular feed for guests.
* Includes a sidebar with community recommendations and personal shortcuts.
* @returns The home page component with infinite scrolling posts.
*/
export default function Home() {
const [user, loadingUser] = useAuthState(auth);
Expand Down Expand Up @@ -54,7 +56,7 @@
if (communityStateValue.snippetFetched) {
fetchPosts(true);
}
}, [communityStateValue.snippetFetched, user, communityIds.length]);

Check warning on line 59 in app/page.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'fetchPosts'. Either include it or remove the dependency array

/**
* Loads the home feed for unauthenticated users.
Expand All @@ -65,7 +67,7 @@
if (!user && !loadingUser) {
fetchPosts(true);
}
}, [user, loadingUser]);

Check warning on line 70 in app/page.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'fetchPosts'. Either include it or remove the dependency array

/**
* Posts need to exist before trying to fetch votes for posts
Expand All @@ -82,7 +84,7 @@
}));
};
}
}, [user, postStateValue.posts]);

Check warning on line 87 in app/page.tsx

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has missing dependencies: 'getPostVotes' and 'setPostStateValue'. Either include them or remove the dependency array

return (
<PageContent>
Expand Down
7 changes: 4 additions & 3 deletions app/providers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import { useEffect, useState } from "react";
import EmotionRegistry from "./emotion-registry";

/**
* Wraps the app with global providers for state, styling, theming, and layout shell.
* @param children - Next.js page content to render inside the provider tree.
* @returns Provider hierarchy with a mounted flag to avoid hydration issues for the toaster.
* The root provider component that initializes the application's global context.
* Orchestrates state management (Jotai), styling (Emotion, Chakra UI), theming (ColorMode), and the global layout shell.
* @param children - The application content to be wrapped by the providers.
* @returns A nested provider tree ensuring all global services are available.
*/
export function Providers({ children }: { children: React.ReactNode }) {
const [mounted, setMounted] = useState(false);
Expand Down
4 changes: 2 additions & 2 deletions atoms/authModalAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const defaultModalState: AuthModalState = {
};

/**
* Controls whether the auth modal is visible and which screen is active.
* @returns Jotai atom with open flag and active view.
* A Jotai atom that manages the state of the authentication modal.
* It tracks whether the modal is open and which view (login, signup, or reset password) is currently active.
*/
export const authModalStateAtom = atom<AuthModalState>(defaultModalState);
5 changes: 3 additions & 2 deletions atoms/communitiesAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export const defaultCommunityState: CommunityState = {
};

/**
* Stores the user's community snippets and the active community context.
* @returns Jotai atom tracking membership data and whether snippets are loaded.
* A Jotai atom that manages the community-related state for the application.
* It stores the user's community membership snippets, the currently active community,
* and a flag indicating whether the snippets have been successfully fetched.
*/
export const communityStateAtom = atom<CommunityState>(defaultCommunityState);
4 changes: 2 additions & 2 deletions atoms/directoryMenuAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const defaultMenuState: DirectoryMenuState = {
};

/**
* Controls the navbar directory dropdown and the currently highlighted item.
* @returns Jotai atom containing open state and selected menu item.
* A Jotai atom that manages the state of the navigation directory menu.
* It tracks whether the menu is open and which menu item is currently selected.
*/
export const directoryMenuAtom = atom<DirectoryMenuState>(defaultMenuState);
5 changes: 3 additions & 2 deletions atoms/postsAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ const defaultPostState: PostState = {
};

/**
* Holds the active post, loaded posts list, and vote cache for the user session.
* @returns Jotai atom that stores post selection and voting state.
* A Jotai atom that manages the post-related state for the application.
* It stores the currently selected post, the list of posts being displayed,
* and the user's voting history for those posts.
*/
export const postStateAtom = atom<PostState>(defaultPostState);
5 changes: 3 additions & 2 deletions atoms/savedPostsAtom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ const defaultSavedPostState: SavedPostState = {
};

/**
* Tracks saved posts modal state and cached posts for the current user.
* @returns Jotai atom with modal visibility, fetch flag, and saved items.
* A Jotai atom that manages the state of the user's saved posts.
* It tracks the list of saved posts, whether the saved posts modal is open,
* and whether the saved posts have been fetched from the backend.
*/
export const savedPostStateAtom = atom<SavedPostState>(defaultSavedPostState);
5 changes: 3 additions & 2 deletions chakra/button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ const solidBase = variantVariants.solid ?? {};
const outlineBase = variantVariants.outline ?? {};

/**
* Custom button recipe used throughout the app.
* Keeps the previous styling from Chakra v2 while leveraging the v3 recipe API.
* A custom component recipe for buttons that extends the default Chakra UI button styles.
* Defines base styles, size variants, and custom visual variants (solid, outline, oauth, action) used across the application.
* Ensures consistent branding and interactive states.
*/
export const buttonRecipe = defineRecipe({
...baseRecipe,
Expand Down
5 changes: 5 additions & 0 deletions chakra/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ import {
} from "@chakra-ui/react";
import { buttonRecipe } from "./button";

/**
* The central configuration for the application's design system using Chakra UI.
* Customizes global styles, color palettes, typography, and component-specific recipes.
* Configured to support both light and dark modes via semantic tokens.
*/
const appConfig = defineConfig({
globalCss: defineGlobalStyles({
body: {
Expand Down
6 changes: 3 additions & 3 deletions components/community/CreatePostLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import useCommunityPermissions from "@/hooks/community/useCommunityPermissions";
type CreatePostProps = {};

/**
* CTA bar that opens the create-post flow or auth modal when clicked.
* Hides itself when the current community blocks posting.
* @returns Input-like control with icons.
* A call-to-action bar that provides a shortcut to the post creation page.
* Automatically handles authentication checks and community-specific posting permissions.
* @returns A styled input-like component that triggers navigation or the auth modal.
*/
const CreatePostLink: React.FC<CreatePostProps> = () => {
const { onClick } = useCallCreatePost(); // hook for creating a new post
Expand Down
5 changes: 3 additions & 2 deletions components/community/PersonalHome.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import React, { useState } from "react";
import CreateCommunityModal from "../modal/create-community/CreateCommunityModal";

/**
* Component for displaying card for creating a new community or post.
* @returns {React.FC} Card for creating a new community or post.
* A sidebar card that provides quick actions for the user's personal home feed.
* Allows users to initiate post creation or open the community creation modal.
* @returns A themed card with action buttons for home feed management.
*/
const PersonalHome: React.FC = () => {
const [open, setOpen] = useState(false); // modal initially closed
Expand Down
7 changes: 4 additions & 3 deletions components/community/RestrictedCommunityBanner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ type RestrictedCommunityBannerProps = {
};

/**
* Lightweight banner used when a user lacks access to a community.
* @param props - Optional title and description overrides.
* @returns Lock icon with supporting text.
* A placeholder banner displayed when a user attempts to view a private or restricted community without permission.
* @param title - Custom title for the restriction message.
* @param description - Custom description explaining the access limitation.
* @returns A centered banner with a lock icon and explanatory text.
*/
const RestrictedCommunityBanner: React.FC<RestrictedCommunityBannerProps> = ({
title = "This community is private",
Expand Down
5 changes: 3 additions & 2 deletions components/layout/GlobalHooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import React, { useEffect } from "react";
import { useAuthState } from "react-firebase-hooks/auth";

/**
* Runs global data bootstrapping for community snippets and saved posts.
* @returns Null render; side effects hydrate atoms based on auth state.
* A headless component that initializes global data based on the user's authentication state.
* Bootstraps community subscriptions and saved posts into global state atoms.
* @returns null, as this component only performs side effects.
*/
const GlobalHooks: React.FC = () => {
useCommunitySnippets();
Expand Down
7 changes: 4 additions & 3 deletions components/layout/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ interface LayoutProps {
}

/**
* Wraps pages with global hooks and the site navbar.
* @param children - Page content to display below the navbar.
* @returns Layout shell rendered on every page.
* The primary layout wrapper for all pages in the application.
* Injects global hooks for data bootstrapping and renders the persistent navbar.
* @param children - The page-specific content to be rendered within the layout.
* @returns A layout shell containing the navbar and main content area.
*/
const Layout: React.FC<LayoutProps> = ({ children }) => {
return (
Expand Down
8 changes: 5 additions & 3 deletions components/layout/PageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ type PageContentProps = {
};

/**
* Two-column responsive layout that expects main content and an optional sidebar.
* @param children - Array-like children where index 0 is main content and index 1 is sidebar.
* @returns Flex container that hides the sidebar on small screens.
* A responsive two-column layout component used for page content.
* Expects two children: the first for the main content area (left) and the second for the sidebar (right).
* The sidebar is hidden on smaller screens.
* @param children - The content to be displayed in the two columns.
* @returns A centered flex container with responsive column widths.
*/
const PageContent: React.FC<PageContentProps> = ({ children }) => {
return (
Expand Down
15 changes: 11 additions & 4 deletions components/modal/ConfirmationDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,17 @@ interface ConfirmationDialogProps {
}

/**
* Generic confirmation dialog used for destructive flows like deletions.
* Stops event propagation so parent click handlers do not fire.
* @param props - Control flags, callbacks, labels, and loading state.
* @returns Modal dialog with confirm and cancel actions.
* A reusable modal dialog for confirming user actions, particularly destructive ones like deletions.
* Provides customizable title, body text, and button labels, with support for loading states.
* @param open - Whether the dialog is currently visible.
* @param onClose - Callback to close the dialog without confirming.
* @param onConfirm - Callback triggered when the user confirms the action.
* @param title - The header text for the dialog.
* @param body - The main message text for the dialog.
* @param confirmButtonText - Custom label for the confirmation button.
* @param cancelButtonText - Custom label for the cancellation button.
* @param isLoading - Whether the confirmation action is currently in progress.
* @returns A themed confirmation modal.
*/
const ConfirmationDialog: React.FC<ConfirmationDialogProps> = ({
open,
Expand Down
6 changes: 6 additions & 0 deletions components/modal/create-community/CreateCommunityModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ type CreateCommunityModalProps = {
handleClose: () => void;
};

/**
* Modal for creating a new community with name validation and privacy selection.
* @param open - Whether the modal is visible.
* @param handleClose - Callback to close the modal.
* @returns Dialog with community creation form.
*/
const CreateCommunityModal: React.FC<CreateCommunityModalProps> = ({
open,
handleClose,
Expand Down
6 changes: 6 additions & 0 deletions components/modal/profile/ProfileModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ type ProfileModalProps = {
handleClose: () => void;
};

/**
* Modal for editing user profile information including display name and profile image.
* @param open - Whether the modal is visible.
* @param handleClose - Callback to close the modal.
* @returns Dialog with profile editing form.
*/
const ProfileModal: React.FC<ProfileModalProps> = ({ open, handleClose }) => {
const [user] = useAuthState(auth);
const { updateImage, removeImage, updateName, loading } = useUserProfile();
Expand Down
6 changes: 6 additions & 0 deletions components/modal/saved-posts/SavedPostsModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,12 @@ import React from "react";
import { LuTrash } from "react-icons/lu";
import { FaReddit } from "react-icons/fa";

/**
* Modal listing saved posts with quick navigation and remove controls.
* Relies on saved post atom for visibility and content.
* Allows users to view their saved posts and navigate to them or their communities.
* @returns Dialog with list items linking to posts and communities.
*/
const SavedPostsModal: React.FC = () => {
const [savedPostState, setSavedPostState] = useAtom(savedPostStateAtom);
const { onRemoveSavedPost } = useSavedPosts();
Expand Down
5 changes: 3 additions & 2 deletions components/navbar/Navbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import RightContent from "./right-content/RightContent";
import SearchInput from "./SearchInput";

/**
* Top navigation bar with branding, search, community directory, and auth-aware actions.
* @returns Responsive navbar that updates based on authentication state.
* The primary navigation header for the application.
* Contains the site logo, community directory (for logged-in users), search input, and user authentication controls.
* @returns A sticky, responsive navbar component.
*/
const Navbar: React.FC = () => {
const [user, loading, error] = useAuthState(auth); // will be passed to child components
Expand Down
Loading