diff --git a/src/app/(about)/about/page.js b/src/app/(about)/about/page.js index dc131c54..5dc7c317 100644 --- a/src/app/(about)/about/page.js +++ b/src/app/(about)/about/page.js @@ -8,6 +8,12 @@ export const metadata = { description: `Here are some details about my self.`, }; +/** + * Renders the About component. + * This component includes an overview cover section, skills section, and a contact message for potential projects. + * + * @returns {JSX.Element} - The rendered JSX element. + */ export default function About() { return ( <> diff --git a/src/app/(about)/contact/page.js b/src/app/(about)/contact/page.js index c9c9743d..1c1b0c82 100644 --- a/src/app/(about)/contact/page.js +++ b/src/app/(about)/contact/page.js @@ -9,6 +9,11 @@ export const metadata = { }; +/** + * Returns the Contact component that renders a section for contacting information. + * + * @returns {JSX.Element} - A React JSX element representing the contact section. + */ export default function Contact() { return (
diff --git a/src/app/blogs/[slug]/page.js b/src/app/blogs/[slug]/page.js index e1afd310..615b4e22 100644 --- a/src/app/blogs/[slug]/page.js +++ b/src/app/blogs/[slug]/page.js @@ -6,10 +6,37 @@ import { allBlogs } from "contentlayer/generated"; import { slug } from "github-slugger"; import Image from "next/image"; +/** + * Generates static parameters for blog slugs. + * + * @async + * @returns {Promise>} - A promise that resolves to an array of objects, each containing a 'slug' property corresponding to a blog's flattened path. + * @throws {Error} - If there is an error during the generation process. + * + * Example usage: + * generateStaticParams().then((params) => { + * console.log(params); + * }).catch((error) => { + * console.error(error); + * }); + */ export async function generateStaticParams() { return allBlogs.map((blog) => ({ slug: blog._raw.flattenedPath })); } +/** + * Generates metadata for a blog post based on the provided parameters. + * + * @param {Object} params - The parameters required to fetch blog metadata. + * @param {string} params.slug - The slug of the blog post to retrieve. + * @returns {Promise} - A promise that resolves to an object containing blog metadata or undefined if no blog is found. + * + * @example + * const params = { slug: 'sample-blog-post' }; + * generateMetadata(params).then(metadata => { + * console.log(metadata); + * }); + */ export async function generateMetadata({ params }) { const blog = allBlogs.find((blog) => blog._raw.flattenedPath === params.slug); if (!blog) { @@ -56,6 +83,13 @@ export async function generateMetadata({ params }) { }; } +/** + * The BlogPage component renders a blog post page based on the provided slug parameter. + * It fetches the blog post data, generates JSON-LD for SEO purposes, and displays the blog content. + * + * @param {Object} params - The parameters object containing the slug of the blog post. + * @returns {JSX.Element} - The JSX representing the blog page. + */ export default function BlogPage({ params }) { const blog = allBlogs.find((blog) => blog._raw.flattenedPath === params.slug); diff --git a/src/app/categories/[slug]/page.js b/src/app/categories/[slug]/page.js index 57e51269..9f308f79 100644 --- a/src/app/categories/[slug]/page.js +++ b/src/app/categories/[slug]/page.js @@ -5,6 +5,16 @@ import GithubSlugger, { slug } from "github-slugger"; const slugger = new GithubSlugger(); +/** + * Generates static parameters for blog paths based on published blogs and their tags. + * + * This function iterates through all published blogs, extracts their tags, + * slugifies the tags to create unique slugs, and generates an array of paths + * including 'all' and each unique tag slug. Only includes tags from published blogs. + * + * @returns {Array<{slug: string}>} - An array of objects containing a slug for each unique tag. + * @throws {Error} If the `allBlogs` variable is not defined or is empty. + */ export async function generateStaticParams() { const categories = []; const paths = [{ slug: "all" }]; @@ -24,6 +34,22 @@ export async function generateStaticParams() { return paths; } +/** + * Generates metadata based on the provided parameters. + * + * @async + * @function generateMetadata + * @param {Object} params - The parameters object containing necessary information. + * @param {string} params.slug - The slug used to determine the title and description of the blogs. + * @returns {Promise} A promise that resolves with an object containing the generated metadata. + * @throws Will throw an error if the params object is missing or if the slug parameter is invalid. + * + * @example + * // Example usage: + * generateMetadata({ slug: "all" }) + * .then(metadata => console.log(metadata)) + * .catch(error => console.error(error)); + */ export async function generateMetadata({ params }) { return { title: `${params.slug.replaceAll("-"," ")} Blogs`, @@ -32,6 +58,13 @@ export async function generateMetadata({ params }) { } +/** + * A React component that renders a category page based on the provided parameters. + * + * @param {Object} params - An object containing route parameters. + * @param {string} params.slug - The current category slug to filter blogs. + * @returns {JSX.Element} - The rendered CategoryPage component. + */ const CategoryPage = ({ params }) => { const allCategories = ["all"]; const blogs = allBlogs.filter((blog) => { diff --git a/src/app/layout.js b/src/app/layout.js index ddcf7de2..cac28f9d 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -53,6 +53,26 @@ export const metadata = { }, }; +/** + * A React component that serves as the root layout for the application. + * + * @param {Object} props - The properties passed to this component. + * @param {React.ReactNode} props.children - Content to be rendered within the layout. + * @returns {React.ReactNode} - The rendered React element representing the root layout. + * + * This component renders a basic HTML structure with a header, footer, + * and a body that includes conditional rendering of a dark mode theme + * based on user preference or system settings. It also includes a script tag for + * handling theme switching and a class name for font styling using the `cx` utility. + * + * Example usage: + * + * ```jsx + * + * + * + * ``` + */ export default function RootLayout({ children }) { return ( diff --git a/src/app/manifest.js b/src/app/manifest.js index 413a5712..7307b0dc 100644 --- a/src/app/manifest.js +++ b/src/app/manifest.js @@ -1,3 +1,17 @@ +/** + * Generates the manifest configuration for a Next.js application. + * + * @returns {Object} - The manifest configuration object. + * @property {string} name - The name of the application. + * @property {string} short_name - A shorter version of the application name, used in places where space is limited. + * @property {string} description - A brief description of the application. + * @property {string} start_url - The URL that the browser loads when opening the application. + * @property {string} display - Defines how the web app should be displayed to users. Possible values are 'fullscreen', 'standalone', 'minimal-ui', and 'browser'. + * @property {Array} icons - An array of icon objects, each representing an image that can be used by browsers on homescreens. + * @property {string} src - The URL of the icon file. + * @property {string} sizes - A string indicating the size of the icon in pixels. + * @property {string} type - The MIME type of the icon file, typically 'image/png'. + */ export default function manifest() { return { name: 'Next.js App', diff --git a/src/app/not-found.js b/src/app/not-found.js index d3e580f2..aeeb2df7 100644 --- a/src/app/not-found.js +++ b/src/app/not-found.js @@ -1,5 +1,11 @@ import Link from "next/link"; +/** + * Represents a React functional component that renders a 404 error page. + * + * @function + * @returns {JSX.Element} - A JSX element representing the 404 error page. + */ export default function NotFound() { return (
diff --git a/src/components/About/AboutCoverSection.js b/src/components/About/AboutCoverSection.js index bcee1b80..42c47b3d 100644 --- a/src/components/About/AboutCoverSection.js +++ b/src/components/About/AboutCoverSection.js @@ -2,6 +2,10 @@ import Image from 'next/image' import React from 'react' import profileCharacter from "../../../public/character.png" +/** + * React functional component that renders an about cover section with an image and text content. + * @returns {JSX.Element} - The rendered JSX element of the about cover section. + */ const AboutCoverSection = () => { return (
diff --git a/src/components/About/InsightRoll.js b/src/components/About/InsightRoll.js index 2046ed77..80abfdf5 100644 --- a/src/components/About/InsightRoll.js +++ b/src/components/About/InsightRoll.js @@ -1,5 +1,12 @@ import React from "react"; +/** + * A React component that renders a div with a list of insights, styled to roll across the screen. + * + * @param {Object} props - The properties for this component. + * @param {Array} props.insights - An array of strings representing the insights to display. + * @returns {JSX.Element} A React element representing the InsightRoll component. + */ const InsightRoll = ({ insights }) => { return (
diff --git a/src/components/About/Skills.js b/src/components/About/Skills.js index ec7c5d95..05a02f2e 100644 --- a/src/components/About/Skills.js +++ b/src/components/About/Skills.js @@ -14,6 +14,11 @@ const SkillList = [ "sanity", ]; +/** + * Represents a component that displays the list of skills a person is comfortable with. + * + * @returns {JSX.Element} The JSX element representing the skills section. + */ const Skills = () => { return (
{ return (
diff --git a/src/components/Blog/BlogLayoutThree.js b/src/components/Blog/BlogLayoutThree.js index 9e8cca22..2bfd8cec 100644 --- a/src/components/Blog/BlogLayoutThree.js +++ b/src/components/Blog/BlogLayoutThree.js @@ -3,6 +3,23 @@ import Image from "next/image"; import Link from "next/link"; import React from "react"; +/** + * React component for rendering a blog post layout. + * + * @param {Object} props - The properties object. + * @param {Object} props.blog - The blog post data. + * @param {string} props.blog.url - The URL of the blog post. + * @param {Object} props.blog.image - The image data for the blog post. + * @param {string} props.blog.image.filePath - The file path of the blog post image. + * @param {string} props.blog.image.blurhashDataUrl - The blurhash data URL for lazy loading. + * @param {number} props.blog.image.width - The width of the blog post image. + * @param {number} props.blog.image.height - The height of the blog post image. + * @param {Array} props.blog.tags - The tags associated with the blog post. + * @param {string} props.blog.title - The title of the blog post. + * @param {string} props.blog.publishedAt - The publication date of the blog post in ISO format. + * + * @returns {JSX.Element} - The rendered BlogLayoutThree component. + */ const BlogLayoutThree = ({ blog }) => { return (
diff --git a/src/components/Blog/BlogLayoutTwo.js b/src/components/Blog/BlogLayoutTwo.js index cbb163bd..af94adb8 100644 --- a/src/components/Blog/BlogLayoutTwo.js +++ b/src/components/Blog/BlogLayoutTwo.js @@ -3,6 +3,20 @@ import Image from "next/image"; import Link from "next/link"; import React from "react"; +/** + * Renders a blog layout with an image and text content. + * + * @param {Object} props - The component's properties. + * @param {Object} props.blog - The blog object containing details to display. + * @param {string} props.blog.url - The URL of the blog post. + * @param {string} props.blog.image.filePath - The file path of the blog image. + * @param {string} props.blog.image.blurhashDataUrl - The blur hash data URL for the blog image. + * @param {string} props.blog.title - The title of the blog post. + * @param {Array} props.blog.tags - An array of tags associated with the blog post. + * @param {Date} props.blog.publishedAt - The date the blog post was published. + * + * @returns {JSX.Element} - The rendered blog layout component. + */ const BlogLayoutTwo = ({ blog }) => { return (
diff --git a/src/components/Blog/Categories.js b/src/components/Blog/Categories.js index bab04ac4..28aec48a 100644 --- a/src/components/Blog/Categories.js +++ b/src/components/Blog/Categories.js @@ -2,6 +2,17 @@ import { slug } from "github-slugger"; import React from "react"; import Category from "./Category"; +/** + * A React component that renders a list of categories with links. + * + * @param {Object} props - The props object for the Categories component. + * @param {Array} props.categories - An array of category slugs. + * @param {string} props.currentSlug - The current category slug. + * @returns {JSX.Element} A React element representing the list of categories. + * + * @example + * + */ const Categories = ({ categories, currentSlug }) => { return (
diff --git a/src/components/Blog/Category.js b/src/components/Blog/Category.js index 8eab7808..8988bb8e 100644 --- a/src/components/Blog/Category.js +++ b/src/components/Blog/Category.js @@ -2,6 +2,17 @@ import { cx } from "@/src/utils"; import Link from "next/link"; import React from "react"; +/** + * A functional component that renders a category link with optional styling and active state handling. + * + * @param {Object} props - The properties passed to the component. + * @param {string} [props.link="#"] - The URL to navigate to when the link is clicked. Defaults to "#". + * @param {string} props.name - The name of the category displayed on the link. + * @param {boolean} [props.active=false] - Determines if the category is currently active, affecting its style. Defaults to false. + * @param {...Object} props - Additional properties that can be passed to the underlying Link component. + * + * @returns {JSX.Element} A JSX element representing a styled link for a category. + */ const Category = ({ link = "#", name, active, ...props }) => { return ( + */ const RenderMdx = ({blog}) => { const MDXContent = useMDXComponent(blog.body.code) diff --git a/src/components/Blog/ViewCounter.js b/src/components/Blog/ViewCounter.js index 38764726..8e87f7fb 100644 --- a/src/components/Blog/ViewCounter.js +++ b/src/components/Blog/ViewCounter.js @@ -4,10 +4,36 @@ import React, { useEffect, useState } from "react"; const supabase = createClientComponentClient(); +/** + * A React component that renders the number of views for a specific slug. + * + * @param {Object} props - The properties passed to the component. + * @param {string} props.slug - The unique identifier for the content being viewed. + * @param {boolean} [props.noCount=false] - Optional flag to disable view counting. Defaults to `false`. + * @param {boolean} [props.showCount=true] - Optional flag to control whether to display the count of views. Defaults to `true`. + * @returns {JSX.Element} - The rendered component. + */ const ViewCounter = ({ slug, noCount = false, showCount = true }) => { const [views, setViews] = useState(0); useEffect(() => { + /** + * Asynchronously increments the view count for a given slug using Supabase RPC. + * + * @async + * @function + * @param {string} slug - The slug for which to increment the view count. + * @returns {Promise} A promise that resolves when the view count has been incremented, or rejects if an error occurs. + * + * @example + * try { + * await incrementView("example-slug"); + * } catch (error) { + * console.error("Failed to increment view count:", error); + * } + * + * @throws {Error} If there is an error during the RPC call or in the catch block. + */ const incrementView = async () => { try { let { error } = await supabase.rpc("increment", { @@ -32,6 +58,18 @@ const ViewCounter = ({ slug, noCount = false, showCount = true }) => { }, [slug, noCount]); useEffect(() => { + /** + * Increments the view count for a given slug. + * + * @async + * @function getViews + * @param {string} slug - The unique identifier of the resource whose views need to be incremented. + * @returns {undefined} + * @throws {Error} Throws an error if there is an issue fetching or updating the view count. + * + * Example usage: + * getViews("example-slug"); + */ const getViews = async () => { try { let { data, error } = await supabase diff --git a/src/components/Contact/ContactForm.js b/src/components/Contact/ContactForm.js index 021d31c8..321d20ac 100644 --- a/src/components/Contact/ContactForm.js +++ b/src/components/Contact/ContactForm.js @@ -2,12 +2,25 @@ import React from "react"; import { useForm } from "react-hook-form"; +/** + * Represents a contact form component. + * + * This component provides a form for users to submit their contact information and project details. + * It uses the `useForm` hook from a custom form handling library to manage form state and validation. + * + * @returns {JSX.Element} - Returns the JSX representation of the contact form. + */ export default function ContactForm() { const { register, handleSubmit, formState: { errors }, } = useForm(); + /** + * Handles the submission of data. + * + * @param {Object} data - The data to be submitted. + */ const onSubmit = (data) => console.log(data); console.log(errors); diff --git a/src/components/Contact/LottieAnimation.js b/src/components/Contact/LottieAnimation.js index 6f6019e7..6f6ed9d2 100644 --- a/src/components/Contact/LottieAnimation.js +++ b/src/components/Contact/LottieAnimation.js @@ -3,6 +3,11 @@ import React from 'react'; import { DotLottiePlayer } from '@dotlottie/react-player'; import '@dotlottie/react-player/dist/index.css'; +/** + * Returns a React component that renders a Lottie animation using the DotLottiePlayer. + * + * @returns {React.Component} A React component representing the Lottie animation player. + */ const LottieAnimation = () => { return ( + */ const Tag = ({ link = "#", name, ...props }) => { return ( { const { register, handleSubmit, formState: { errors }, } = useForm(); + /** + * Handles form submission by logging the data to the console. + * + * @param {Object} data - The data submitted via the form. + */ const onSubmit = (data) => console.log(data); console.log(errors); diff --git a/src/components/Header/Logo.js b/src/components/Header/Logo.js index 7cf904ce..fc6c6cc4 100644 --- a/src/components/Header/Logo.js +++ b/src/components/Header/Logo.js @@ -2,6 +2,11 @@ import Image from "next/image" import Link from "next/link" import profileImg from "@/public/profile-img.png" +/** + * React functional component representing the logo of CodeBucks. + * + * @returns {JSX.Element} - The JSX element representing the logo. + */ const Logo = () => { return ( diff --git a/src/components/Header/index.js b/src/components/Header/index.js index c04fe9bd..7dd33f63 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -7,11 +7,22 @@ import { useThemeSwitch } from "../Hooks/useThemeSwitch"; import { useState } from "react"; import { cx } from "@/src/utils"; +/** + * Represents the header component of the application, featuring navigation, theme toggle, and social media links. + * + * @returns {JSX.Element} The rendered header component. + */ const Header = () => { const [mode, setMode] = useThemeSwitch(); const [click, setClick] = useState(false); +/** + * Toggles the state of the 'click' variable. + * This function is typically used to handle click events or other actions that require flipping a boolean state. + * + * @function toggle + */ const toggle = () =>{ setClick(!click) } diff --git a/src/components/Home/HomeCoverSection.js b/src/components/Home/HomeCoverSection.js index 1030dd3f..3531badb 100644 --- a/src/components/Home/HomeCoverSection.js +++ b/src/components/Home/HomeCoverSection.js @@ -5,6 +5,16 @@ import React from 'react' import Tag from '../Elements/Tag'; import { slug } from 'github-slugger'; +/** + * A React component that renders a home cover section with the most recent blog post. + * + * @param {Object} props - The component props. + * @param {Array} props.blogs - An array of blog objects to be sorted and displayed. + * @returns {JSX.Element} - Returns the JSX for the HomeCoverSection component. + * + * @example + * + */ const HomeCoverSection = ({blogs}) => { const sortedBlogs = sortBlogs(blogs); diff --git a/src/components/Home/RecentPosts.js b/src/components/Home/RecentPosts.js index 9e715f9a..feb01fcf 100644 --- a/src/components/Home/RecentPosts.js +++ b/src/components/Home/RecentPosts.js @@ -3,6 +3,13 @@ import Link from "next/link"; import React from "react"; import BlogLayoutThree from "../Blog/BlogLayoutThree"; +/** + * A React component that renders a section displaying recent blog posts. + * + * @param {Object} props - The properties for the RecentPosts component. + * @param {Array} props.blogs - An array of blog objects to display. + * @returns {React.ReactNode} - The rendered RecentPosts component. + */ const RecentPosts = ({ blogs }) => { const sortedBlogs = sortBlogs(blogs); return ( diff --git a/src/components/Hooks/useThemeSwitch.js b/src/components/Hooks/useThemeSwitch.js index ee66af3d..97cb9607 100644 --- a/src/components/Hooks/useThemeSwitch.js +++ b/src/components/Hooks/useThemeSwitch.js @@ -6,6 +6,12 @@ export function useThemeSwitch() { const preferDarkQuery = "(prefers-color-schema:dark)"; const storageKey = "theme"; + /** + * Toggles the theme of the application between "dark" and other themes. + * + * @param {string} theme - The theme to set. Must be either "dark" or another valid theme. + * @throws {Error} If an invalid theme is provided. + */ const toggleTheme = (theme) => { if (theme === "dark") { document.documentElement.classList.add("dark"); @@ -15,6 +21,11 @@ export function useThemeSwitch() { window.localStorage.setItem(storageKey, theme); }; + /** + * Retrieves the user's preference from local storage or system settings. + * + * @returns {string} - The user's preferred theme ("dark" or "light"). + */ const getUserPreference = () => { const userPref = window.localStorage.getItem(storageKey); if (userPref) { @@ -27,6 +38,12 @@ export function useThemeSwitch() { useEffect(() => { const mediaQuery = window.matchMedia(preferDarkQuery); + /** + * Handles a change event by updating the user preference mode, + * setting the new mode, and toggling the theme accordingly. + * + * @returns {void} + */ const handleChange = () => { const newMode = getUserPreference(); setMode(newMode); diff --git a/src/components/Icons.js b/src/components/Icons.js index f80ab3cc..9c3469a2 100644 --- a/src/components/Icons.js +++ b/src/components/Icons.js @@ -1,6 +1,16 @@ import React from "react"; import { cx } from "../utils"; +/** + * A React component that renders a sun icon with animation effects. + * + * @param {Object} props - The component's properties. + * @prop {string} [props.className] - Additional CSS classes to be applied to the SVG element. + * @returns {JSX.Element} - The rendered SunIcon component. + * + * @example + * + */ export const SunIcon = ({ className, ...rest }) => ( ( ); +/** + * Represents a functional component that renders an LinkedIn icon. + * + * @param {Object} props - The properties for the LinkedInIcon component. + * @param {string} [props.className] - Additional CSS class names to apply to the SVG element. + * @returns {JSX.Element} A React JSX element representing the LinkedIn icon. + * + * @example + * + */ export const LinkedinIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component that renders a Twitter icon. + * + * @param {Object} props - The properties for the TwitterIcon component. + * @prop {string} [className] - Additional CSS classes to be applied to the icon container. + * @returns {JSX.Element} - The JSX element representing the Twitter icon. + * + * @example + * + */ export const TwitterIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component that renders an icon representing GitHub. + * + * @param {Object} props - The component's properties. + * @param {string} [props.className] - Additional CSS classes to apply to the icon. + * @returns {JSX.Element} - The rendered SVG element with the GitHub icon. + * + * @example + * + */ export const GithubIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component representing the Dribbble icon. + * + * @param {Object} props - The properties of the icon component. + * @param {string} [props.className] - Additional CSS classes to apply to the SVG element. + * @returns {JSX.Element} The rendered Dribbble icon as an SVG element. + * + * @example + * + */ export const DribbbleIcon = ({ className, ...rest }) => { return ( classNames.filter(Boolean).join(" "); +/** + * Sorts an array of blog objects by their published date in descending order. + * + * @param {Array} blogs - An array of blog objects, each with a 'publishedAt' property. + * @returns {Array} A new array of sorted blog objects. + * @throws {TypeError} If the input is not an array or if any blog object does not have a 'publishedAt' property in the correct format. + * + * @example + * const blogs = [ + * { title: "Blog Post 1", publishedAt: "2023-01-01" }, + * { title: "Blog Post 2", publishedAt: "2023-01-02" } + * ]; + * const sortedBlogs = sortBlogs(blogs); + * console.log(sortedBlogs); // Output will be the array sorted by 'publishedAt' in descending order + */ export const sortBlogs = (blogs) => { return blogs .slice()