diff --git a/src/app/(about)/about/page.js b/src/app/(about)/about/page.js index dc131c54..6b3db395 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 main page of the application with an introduction section, + * skills showcase, and a contact form to get in touch. + * + * @returns {JSX.Element} - The JSX element representing the about page. + */ export default function About() { return ( <> diff --git a/src/app/(about)/contact/page.js b/src/app/(about)/contact/page.js index c9c9743d..b28fd717 100644 --- a/src/app/(about)/contact/page.js +++ b/src/app/(about)/contact/page.js @@ -9,6 +9,11 @@ export const metadata = { }; +/** + * Represents a functional component that renders a contact section with a Lottie animation and a contact form. + * + * @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..9b7eb442 100644 --- a/src/app/blogs/[slug]/page.js +++ b/src/app/blogs/[slug]/page.js @@ -6,10 +6,32 @@ import { allBlogs } from "contentlayer/generated"; import { slug } from "github-slugger"; import Image from "next/image"; +/** + * Generates static parameters for blog slugs. + * + * @async + * @returns {Array<{ slug: string }>} An array of objects containing the slug for each blog. + * + * @throws {Error} If there is an error processing the blogs. + */ export async function generateStaticParams() { return allBlogs.map((blog) => ({ slug: blog._raw.flattenedPath })); } +/** + * Generates metadata for a blog post based on the provided parameters. + * + * @async + * @function generateMetadata + * @param {Object} params - An object containing the parameters for the function. + * @param {string} params.slug - The slug of the blog post to fetch metadata for. + * @returns {Promise} - A Promise that resolves with an object containing blog metadata or null if no blog is found. + * + * @example + * generateMetadata({ slug: 'example-blog' }).then(metadata => { + * console.log(metadata); + * }); + */ export async function generateMetadata({ params }) { const blog = allBlogs.find((blog) => blog._raw.flattenedPath === params.slug); if (!blog) { @@ -56,6 +78,14 @@ export async function generateMetadata({ params }) { }; } +/** + * React component that renders an individual blog post page. + * + * @param {Object} params - The parameters passed to the component. + * @param {string} params.slug - The slug of the blog post. + * + * @returns {JSX.Element} The rendered BlogPage component. + */ 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..5313ec80 100644 --- a/src/app/categories/[slug]/page.js +++ b/src/app/categories/[slug]/page.js @@ -5,6 +5,15 @@ import GithubSlugger, { slug } from "github-slugger"; const slugger = new GithubSlugger(); +/** + * Generates static parameters for blog paths. + * + * This function iterates through all published blogs and extracts unique tags, + * slugifying them to create category slugs. It then constructs an array of path objects, + * each representing a blog category or the 'all' category. + * + * @returns {Array<{slug: string}>} - An array of path objects, each with a 'slug' property. + */ export async function generateStaticParams() { const categories = []; const paths = [{ slug: "all" }]; @@ -24,6 +33,33 @@ export async function generateStaticParams() { return paths; } +/** + * Generates metadata for blog pages based on the provided parameters. + * + * @param {Object} params - The parameters object containing necessary data. + * @param {string} params.slug - The slug of the blog or "all" if no specific blog is selected. + * @returns {Object} - An object containing the title and description for the blog page. + * + * @example + * const metadata = await generateMetadata({ params: { slug: "javascript" } }); + * console.log(metadata); + * // Output: + * // { + * // title: 'JavaScript Blogs', + * // description: 'Learn more about JavaScript through our collection of expert blogs and tutorials' + * // } + * + * @example + * const allBlogsMetadata = await generateMetadata({ params: { slug: "all" } }); + * console.log(allBlogsMetadata); + * // Output: + * // { + * // title: 'All Blogs', + * // description: 'Learn more about web development through our collection of expert blogs and tutorials' + * // } + * + * @throws {Error} - If the params object is missing or does not contain a slug. + */ export async function generateMetadata({ params }) { return { title: `${params.slug.replaceAll("-"," ")} Blogs`, @@ -32,6 +68,13 @@ export async function generateMetadata({ params }) { } +/** + * A React component that renders a category page based on the provided parameters. + * + * @param {Object} params - The URL parameters. + * @param {string} params.slug - The slug of the category to filter by. If 'all', displays all blogs. + * @returns {JSX.Element} A React element representing the category page. + */ 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..3cbd0560 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -53,6 +53,16 @@ export const metadata = { }, }; +/** + * The root layout component of the application. + * This component provides the structure for the entire application, + * including the HTML structure, body styling, theme switching script, + * header, children components, and footer. + * + * @param {Object} props - The properties passed to the RootLayout component. + * @param {JSX.Element} props.children - The child components to be rendered within the root layout. + * @returns {JSX.Element} - The JSX element representing the root layout of the application. + */ export default function RootLayout({ children }) { return ( diff --git a/src/app/manifest.js b/src/app/manifest.js index 413a5712..282fcea3 100644 --- a/src/app/manifest.js +++ b/src/app/manifest.js @@ -1,3 +1,8 @@ +/** + * Generates the manifest object for a Next.js application. + * + * @returns {Object} - The manifest object containing various configuration properties. + */ 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..c7d467d7 100644 --- a/src/app/not-found.js +++ b/src/app/not-found.js @@ -1,5 +1,15 @@ import Link from "next/link"; +/** + * A React component that renders a "404 Page Not Found" error page. + * + * @returns {JSX.Element} The rendered "404 Page Not Found" page. + * + * Example usage: + * ``` + * + * ``` + */ export default function NotFound() { return (
diff --git a/src/app/page.js b/src/app/page.js index 90f654e4..e9c5fc05 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -3,6 +3,13 @@ import HomeCoverSection from "../components/Home/HomeCoverSection"; import FeaturedPosts from "../components/Home/FeaturedPosts"; import RecentPosts from "../components/Home/RecentPosts"; +/** + * The main component representing the home page of the application. + * It renders a `main` element containing a cover section, featured posts, and recent posts. + * + * @function + * @returns {JSX.Element} - A JSX representation of the Home component. + */ export default function Home() { return ( diff --git a/src/components/About/AboutCoverSection.js b/src/components/About/AboutCoverSection.js index bcee1b80..671fd8b4 100644 --- a/src/components/About/AboutCoverSection.js +++ b/src/components/About/AboutCoverSection.js @@ -2,6 +2,13 @@ import Image from 'next/image' import React from 'react' import profileCharacter from "../../../public/character.png" +/** + * React functional component that renders an about cover section. + * This section includes an image on the left and text content on the right, + * featuring a motivational mantra, description, and personal attributes. + * + * @returns {React.ReactNode} - The rendered AboutCoverSection component. + */ const AboutCoverSection = () => { return (
diff --git a/src/components/About/InsightRoll.js b/src/components/About/InsightRoll.js index 2046ed77..14c14180 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 containing insights with rolling animation. + * + * @param {Object} props - The props object for the component. + * @param {Array} props.insights - An array of strings representing the insights to be displayed. + * @returns {JSX.Element} - The rendered JSX 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..3cd9e97e 100644 --- a/src/components/About/Skills.js +++ b/src/components/About/Skills.js @@ -14,6 +14,11 @@ const SkillList = [ "sanity", ]; +/** + * React functional component that renders a section showcasing the skills of the individual. + * + * @returns {React.ReactNode} - The rendered JSX for the skill list section. + */ const Skills = () => { return (
+ */ const BlogDetails = ({ blog, slug: blogSlug }) => { return (
diff --git a/src/components/Blog/BlogLayoutOne.js b/src/components/Blog/BlogLayoutOne.js index c4b31d98..1a1e252b 100644 --- a/src/components/Blog/BlogLayoutOne.js +++ b/src/components/Blog/BlogLayoutOne.js @@ -4,6 +4,16 @@ import Link from "next/link"; import Image from "next/image"; import { slug } from "github-slugger"; +/** + * Renders a blog layout with a given blog object. + * + * @param {Object} props - The component props. + * @param {Object} props.blog - The blog object containing details about the blog post. + * @returns {JSX.Element} - The rendered blog layout. + * + * Example: + * + */ const BlogLayoutOne = ({ blog }) => { return (
diff --git a/src/components/Blog/BlogLayoutThree.js b/src/components/Blog/BlogLayoutThree.js index 9e8cca22..ebbda478 100644 --- a/src/components/Blog/BlogLayoutThree.js +++ b/src/components/Blog/BlogLayoutThree.js @@ -3,6 +3,21 @@ import Image from "next/image"; import Link from "next/link"; import React from "react"; +/** + * A React component representing a blog layout with specific styling and functionality. + * + * @param {Object} props - The props for the BlogLayoutThree component. + * @param {Object} props.blog - The blog object containing details about the blog post. + * @param {string} props.blog.url - The URL of the blog post. + * @param {Object} props.blog.image - The image object containing details about the blog's image. + * @param {string} props.blog.image.filePath - The file path of the blog's image. + * @param {string} props.blog.image.blurhashDataUrl - The blurhash data URL for the 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 publication date of the blog post. + * + * @returns {React.ReactNode} - The rendered BlogLayoutThree component. + */ const BlogLayoutThree = ({ blog }) => { return (
diff --git a/src/components/Blog/BlogLayoutTwo.js b/src/components/Blog/BlogLayoutTwo.js index cbb163bd..88eb5767 100644 --- a/src/components/Blog/BlogLayoutTwo.js +++ b/src/components/Blog/BlogLayoutTwo.js @@ -3,6 +3,13 @@ import Image from "next/image"; import Link from "next/link"; import React from "react"; +/** + * A React component representing the layout of a blog post. + * + * @param {Object} props - The props for the BlogLayoutTwo component. + * @param {Object} props.blog - The blog post data to be displayed. + * @returns {JSX.Element} - The rendered BlogLayoutTwo component. + */ const BlogLayoutTwo = ({ blog }) => { return (
diff --git a/src/components/Blog/Categories.js b/src/components/Blog/Categories.js index bab04ac4..3a3365b5 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"; +/** + * Renders a container with category links. + * + * @param {Object} props - The component props. + * @param {Array} props.categories - An array of category slugs. + * @param {String} props.currentSlug - The current active category slug. + * @returns {JSX.Element} A JSX element representing the Categories component. + * + * @example + * + */ const Categories = ({ categories, currentSlug }) => { return (
diff --git a/src/components/Blog/Category.js b/src/components/Blog/Category.js index 8eab7808..ebe1e45c 100644 --- a/src/components/Blog/Category.js +++ b/src/components/Blog/Category.js @@ -2,6 +2,16 @@ import { cx } from "@/src/utils"; import Link from "next/link"; import React from "react"; +/** + * A component representing a category link with optional styling. + * + * @param {Object} props - The properties for the Category component. + * @param {string} [props.link="#"] - The URL to which the link should navigate. Default is '#'. + * @param {string} props.name - The name of the category, displayed as the text of the link. + * @param {boolean} [props.active=false] - Whether the category is currently active. If true, applies different styles. + * @param {...Object} props - Additional properties to be spread onto the Link component. + * @returns {React.ReactNode} - The rendered Category component as a styled . + */ 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..9f77d0e9 100644 --- a/src/components/Blog/ViewCounter.js +++ b/src/components/Blog/ViewCounter.js @@ -4,10 +4,35 @@ import React, { useEffect, useState } from "react"; const supabase = createClientComponentClient(); +/** + * A React component that displays and increments the view count for a given slug. + * + * @param {Object} props - The properties passed to the ViewCounter component. + * @param {string} props.slug - The unique identifier for the content. + * @param {boolean} [props.noCount=false] - If true, the view count will not be incremented. + * @param {boolean} [props.showCount=true] - If false, the view count display will not be shown. + */ 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 of the item to update. + * @returns {Promise} A Promise that resolves when the operation is complete. + * @throws {Error} If an error occurs during the RPC call or while handling the response. + * + * @example + * try { + * await incrementView("example-slug"); + * console.log("View count incremented successfully."); + * } catch (error) { + * console.error("Failed to increment view count:", error); + * } + */ const incrementView = async () => { try { let { error } = await supabase.rpc("increment", { @@ -32,6 +57,16 @@ const ViewCounter = ({ slug, noCount = false, showCount = true }) => { }, [slug, noCount]); useEffect(() => { + /** + * Asynchronously increments the view count for a given slug using Supabase. + * + * @async + * @function + * @param {string} slug - The unique identifier for the resource whose views need to be incremented. + * @returns {Promise} A promise that resolves when the view count has been successfully updated or rejects with an error if there's a failure. + * + * @throws {Error} If an error occurs while fetching or updating the view count. + */ 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..d1067993 100644 --- a/src/components/Contact/ContactForm.js +++ b/src/components/Contact/ContactForm.js @@ -2,12 +2,22 @@ import React from "react"; import { useForm } from "react-hook-form"; +/** + * A functional component that renders a contact form for users to submit their information and project details. + * + * @returns {JSX.Element} - The rendered contact form. + */ export default function ContactForm() { const { register, handleSubmit, formState: { errors }, } = useForm(); + /** + * Handles the submission of data by logging it to the console. + * + * @param {any} data - The data to be submitted. + */ const onSubmit = (data) => console.log(data); console.log(errors); diff --git a/src/components/Elements/Tag.js b/src/components/Elements/Tag.js index 0dfdaf6b..981c3710 100644 --- a/src/components/Elements/Tag.js +++ b/src/components/Elements/Tag.js @@ -2,6 +2,19 @@ import { cx } from "@/src/utils"; import Link from "next/link"; import React from "react"; +/** + * A functional component that renders a styled link button. + * + * @param {Object} props - The props object containing the component properties. + * @param {string} [props.link="#"] - The URL to navigate to when the tag is clicked. Defaults to '#'. + * @param {string} props.name - The name or label of the tag displayed on the button. + * @param {string} [props.className] - Additional CSS classes to apply to the button for custom styling. + * + * @returns {JSX.Element} - A JSX element representing the styled link button. + * + * @example + * + */ 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 from 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..8d232768 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" +/** + * Represents the Logo component which renders the CodeBucks logo with a link to the homepage. + * + * @returns {JSX.Element} - The rendered Logo component. + */ const Logo = () => { return ( diff --git a/src/components/Header/index.js b/src/components/Header/index.js index c04fe9bd..ba1aaab5 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -7,11 +7,28 @@ import { useThemeSwitch } from "../Hooks/useThemeSwitch"; import { useState } from "react"; import { cx } from "@/src/utils"; +/** + * A React functional component that renders a header with various elements including a logo, + * a hamburger menu for mobile view, navigation links, and social media icons. + * + * @returns {JSX.Element} The rendered header element. + */ const Header = () => { const [mode, setMode] = useThemeSwitch(); const [click, setClick] = useState(false); +/** + * Toggles the state of a boolean variable `click`. + * + * This function is intended to flip the value of the `click` variable between true and false. + * + * @function toggle + * @example + * // Before calling toggle(), click is likely false or undefined. + * toggle(); + * // After calling toggle(), click should be true. + */ const toggle = () =>{ setClick(!click) } diff --git a/src/components/Home/FeaturedPosts.js b/src/components/Home/FeaturedPosts.js index 5d0056a2..005b2832 100644 --- a/src/components/Home/FeaturedPosts.js +++ b/src/components/Home/FeaturedPosts.js @@ -3,6 +3,13 @@ import React from "react"; import BlogLayoutOne from "../Blog/BlogLayoutOne"; import BlogLayoutTwo from "../Blog/BlogLayoutTwo"; +/** + * A React component that renders featured posts from a list of blogs. + * + * @param {Object} props - The properties object for the component. + * @param {Array} props.blogs - An array of blog objects to be rendered as featured posts. + * @returns {JSX.Element} - The JSX element representing the FeaturedPosts component. + */ const FeaturedPosts = ({ blogs }) => { const sortedBlogs = sortBlogs(blogs); return
diff --git a/src/components/Home/HomeCoverSection.js b/src/components/Home/HomeCoverSection.js index 1030dd3f..27c03eb6 100644 --- a/src/components/Home/HomeCoverSection.js +++ b/src/components/Home/HomeCoverSection.js @@ -5,6 +5,13 @@ import React from 'react' import Tag from '../Elements/Tag'; import { slug } from 'github-slugger'; +/** + * Renders a section with a blog post, featuring the most recent blog from a list of blogs. + * + * @param {Object} props - The component's properties. + * @param {Array} props.blogs - An array of blog objects to sort and display. + * @returns {JSX.Element} - The rendered HomeCoverSection component. + */ const HomeCoverSection = ({blogs}) => { const sortedBlogs = sortBlogs(blogs); diff --git a/src/components/Home/RecentPosts.js b/src/components/Home/RecentPosts.js index 9e715f9a..40dcfb29 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"; +/** + * Renders a section displaying recent blog posts. + * + * @param {Object} props - The component props. + * @param {Array} props.blogs - An array of blog objects to display. + * @returns {JSX.Element} - A JSX element representing the 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..4f6df5a6 100644 --- a/src/components/Hooks/useThemeSwitch.js +++ b/src/components/Hooks/useThemeSwitch.js @@ -2,10 +2,22 @@ import { useEffect, useState } from "react"; +/** + * Custom hook to manage theme switching functionality. + * + * This hook allows components to toggle between light and dark themes based on user preference or system settings. It listens for changes in the user's preferred color scheme and updates the theme accordingly. + * + * @returns {Array} An array containing the current mode (either "dark" or "light") and a function to set the mode. + */ export function useThemeSwitch() { const preferDarkQuery = "(prefers-color-schema:dark)"; const storageKey = "theme"; + /** + * Toggles the theme of the application between 'dark' and 'light'. + * + * @param {string} theme - The theme to set. Must be either "dark" or "light". + */ const toggleTheme = (theme) => { if (theme === "dark") { document.documentElement.classList.add("dark"); @@ -15,6 +27,11 @@ export function useThemeSwitch() { window.localStorage.setItem(storageKey, theme); }; + /** + * Retrieves user preference from local storage or determines it based on media query. + * + * @returns {string} - The user's preferred theme ("dark" or "light"). + */ const getUserPreference = () => { const userPref = window.localStorage.getItem(storageKey); if (userPref) { @@ -27,6 +44,11 @@ export function useThemeSwitch() { useEffect(() => { const mediaQuery = window.matchMedia(preferDarkQuery); + /** + * Handles changes by updating the mode, setting it, and toggling the theme accordingly. + * + * @function + */ const handleChange = () => { const newMode = getUserPreference(); setMode(newMode); diff --git a/src/components/Icons.js b/src/components/Icons.js index f80ab3cc..5337677f 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 animated transitions. + * + * @param {Object} props - The properties for the SunIcon component. + * @param {string} [props.className] - Additional CSS classes to apply to the SVG element. + * @returns {JSX.Element} - The rendered SunIcon component. + * + * @example + * + */ export const SunIcon = ({ className, ...rest }) => ( ( ); +/** + * A React component that renders a LinkedIn icon. + * + * @param {Object} props - The properties for the LinkedInIcon component. + * @param {string} [props.className] - Additional CSS classes to apply to the SVG element. + * @returns {JSX.Element} The JSX element representing the LinkedIn icon. + * + * @example + * + */ export const LinkedinIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * Renders a Twitter icon as an SVG element. + * + * @param {Object} props - The properties for the TwitterIcon component. + * @param {string} [props.className] - Additional CSS class names to apply to the SVG. + * @returns {JSX.Element} - A React JSX Element representing the Twitter icon. + * + * @example + * + */ export const TwitterIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component that renders a GitHub icon. + * + * @param {Object} props - The props for the GithubIcon component. + * @param {string} [props.className] - Additional classes to apply to the icon. + * @returns {JSX.Element} - The rendered GithubIcon component. + * + * @example + * + */ export const GithubIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component that renders an SVG icon for Dribbble. + * + * @param {Object} props - The properties of the component. + * @param {string} [props.className] - Additional CSS classes to apply to the SVG element. + * @returns {JSX.Element} - A React JSX Element representing the Dribbble icon. + * + * @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 to be sorted. + * @return {Array} - The sorted array of blog objects. + * @throws {Error} - Throws an error if the input is not a valid array. + */ export const sortBlogs = (blogs) => { return blogs .slice()