diff --git a/src/app/(about)/about/page.js b/src/app/(about)/about/page.js index dc131c54..097b6319 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.`, }; +/** + * Functional component that renders the main page of an application or website. + * The component includes sections for cover, skills, and contact information. + * + * @returns {JSX.Element} - Returns a JSX element representing the main content of the page. + */ export default function About() { return ( <> diff --git a/src/app/(about)/contact/page.js b/src/app/(about)/contact/page.js index c9c9743d..acfb9e33 100644 --- a/src/app/(about)/contact/page.js +++ b/src/app/(about)/contact/page.js @@ -9,6 +9,11 @@ export const metadata = { }; +/** + * A React component that renders a contact section with a Lottie animation and a contact form. + * + * @returns {JSX.Element} - The rendered JSX for 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..dca50c3a 100644 --- a/src/app/blogs/[slug]/page.js +++ b/src/app/blogs/[slug]/page.js @@ -10,6 +10,17 @@ 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 object containing the slug of the blog post. + * @param {string} params.slug - The slug of the blog post to fetch metadata for. + * @returns {Promise} - A promise that resolves with an object containing openGraph and twitter properties, or null if no blog is found. + * + * Example: + * const result = await generateMetadata({ slug: "my-blog-post" }); + * console.log(result); + */ export async function generateMetadata({ params }) { const blog = allBlogs.find((blog) => blog._raw.flattenedPath === params.slug); if (!blog) { @@ -56,6 +67,13 @@ export async function generateMetadata({ params }) { }; } +/** + * Generates the blog page content based on the provided parameters. + * + * @param {Object} params - The route parameters containing the slug of the blog post. + * @param {string} params.slug - The unique identifier for the blog post. + * @returns {JSX.Element} - The JSX element 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..b002f2a5 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 routing based on published blog tags. + * + * This function iterates over all blogs to collect unique tag slugs that are marked as published. It constructs a list of paths, + * where each path corresponds to a unique tag slug, and includes an additional path for "all" tags. + * + * @returns {Array} - An array of objects representing the paths to be used in static routing. + * Each object has a property 'slug' which is the slugified tag name or 'all'. + */ export async function generateStaticParams() { const categories = []; const paths = [{ slug: "all" }]; @@ -24,6 +33,25 @@ export async function generateStaticParams() { return paths; } +/** + * Generates metadata for blog pages based on provided parameters. + * + * @async + * @function generateMetadata + * @param {Object} params - The parameters object containing the slug. + * @param {string} params.slug - The slug of the blog category or 'all' for all blogs. + * @returns {Promise} A promise that resolves to an object containing title and description metadata. + * + * Example usage: + * generateMetadata({ params: { slug: "javascript" } }) + * .then(metadata => console.log(metadata)); + * + * This function constructs the metadata for blog pages based on the provided slug. If the slug is 'all', + * it sets the title to "Learn more about web development through our collection of expert blogs and tutorials". + * Otherwise, it sets the title to include the capitalized version of the slug with spaces replacing hyphens. + * + * @throws {Error} Throws an error if params or slug are not provided or are invalid. + */ export async function generateMetadata({ params }) { return { title: `${params.slug.replaceAll("-"," ")} Blogs`, @@ -32,6 +60,18 @@ export async function generateMetadata({ params }) { } +/** @typedef {Object} Params - The parameters object passed to the component. + * @property {string} slug - The category slug. + + * @typedef {Object} Blog - A blog post object. + * @property {Array} tags - An array of tags associated with the blog post. + + * @function CategoryPage + * @param {Params} params - The parameters object containing the category slug. + * @returns {React.ReactNode} - JSX representing the category page component. + + * This function is a React functional component that renders a category page based on the provided category slug. It filters blogs by their tags and displays them along with the list of available categories. + */ 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..1cfa3ac2 100644 --- a/src/app/layout.js +++ b/src/app/layout.js @@ -53,6 +53,18 @@ export const metadata = { }, }; +/** + * Represents the root layout component of an application. + * + * @param {Object} props - The props for the RootLayout component. + * @param {JSX.Element} props.children - The children components to render within the root layout. + * @returns {JSX.Element} The rendered HTML structure with a dark theme switcher script, header, footer, and body content. + * + * Example: + * + * + * + */ export default function RootLayout({ children }) { return ( diff --git a/src/app/manifest.js b/src/app/manifest.js index 413a5712..f969610c 100644 --- a/src/app/manifest.js +++ b/src/app/manifest.js @@ -1,3 +1,17 @@ +/** + * Returns the manifest object for the Next.js App. + * + * @returns {Object} The manifest configuration object. + * - {string} name - The full name of the app. + * - {string} short_name - A shorter version of the app name. + * - {string} description - A brief description of the app. + * - {string} start_url - The URL that the browser should load first when it starts the app. + * - {string} display - The display mode for the app (e.g., 'standalone', 'fullscreen'). + * - {Object[]} icons - An array of icon objects to be used in various contexts. + * - {string} src - The path to the icon file. + * - {string} sizes - The dimensions and type of the icon. + * - {string} type - The MIME type of the icon file. + */ 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..03c99594 100644 --- a/src/app/not-found.js +++ b/src/app/not-found.js @@ -1,5 +1,10 @@ import Link from "next/link"; +/** + * A functional component that renders a 404 error page indicating that a requested page was not found. + * + * @returns {JSX.Element} - The rendered JSX for the 404 error page. + */ export default function NotFound() { return (
diff --git a/src/app/page.js b/src/app/page.js index 90f654e4..03eee999 100644 --- a/src/app/page.js +++ b/src/app/page.js @@ -3,6 +3,11 @@ import HomeCoverSection from "../components/Home/HomeCoverSection"; import FeaturedPosts from "../components/Home/FeaturedPosts"; import RecentPosts from "../components/Home/RecentPosts"; +/** + * The main component of the home page that renders various sections. + * + * @returns {JSX.Element} - The JSX element representing the home page. + */ export default function Home() { return ( diff --git a/src/components/About/AboutCoverSection.js b/src/components/About/AboutCoverSection.js index bcee1b80..19a09baf 100644 --- a/src/components/About/AboutCoverSection.js +++ b/src/components/About/AboutCoverSection.js @@ -2,6 +2,11 @@ import Image from 'next/image' import React from 'react' import profileCharacter from "../../../public/character.png" +/** + * React component representing an About Cover Section with a profile image and inspirational text. + * + * @returns {JSX.Element} - The rendered JSX element for the About Cover Section. + */ const AboutCoverSection = () => { return (
diff --git a/src/components/About/InsightRoll.js b/src/components/About/InsightRoll.js index 2046ed77..a0097752 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 element with a rolling animation containing insights text. + * + * @param {Object} props - The component props. + * @param {Array} props.insights - An array of strings representing the insights to be displayed. + * @returns {JSX.Element} - The rendered InsightRoll component. + */ const InsightRoll = ({ insights }) => { return (
diff --git a/src/components/About/Skills.js b/src/components/About/Skills.js index ec7c5d95..30c8e6d1 100644 --- a/src/components/About/Skills.js +++ b/src/components/About/Skills.js @@ -14,6 +14,11 @@ const SkillList = [ "sanity", ]; +/** + * React component that renders a section listing skills. + * + * @returns {JSX.Element} - The rendered JSX element for the Skills component. + */ const Skills = () => { return (
+ */ const BlogLayoutOne = ({ blog }) => { return (
diff --git a/src/components/Blog/BlogLayoutThree.js b/src/components/Blog/BlogLayoutThree.js index 9e8cca22..ce81f9fe 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"; +/** + * A React component that renders a blog post layout with specific styling and interactivity. + * + * @param {Object} props - The properties for the BlogLayoutThree component. + * @param {Object} props.blog - An object containing details about the blog post. + * @param {string} props.blog.url - The URL of the blog post. + * @param {Object} props.blog.image - An object containing image details. + * @param {string} props.blog.image.filePath - The file path to the blog post's image. + * @param {string} props.blog.image.blurhashDataUrl - The blur hash data URL for the image. + * @param {number} props.blog.image.width - The width of the image. + * @param {number} props.blog.image.height - The height of the image. + * @param {Array} props.blog.tags - An array of tags associated with the blog post. + * @param {string} props.blog.title - The title of the blog post. + * @param {string} props.blog.publishedAt - The date and time when the blog post was published. + * + * @returns {JSX.Element} - A React element representing the blog post layout. + */ const BlogLayoutThree = ({ blog }) => { return (
diff --git a/src/components/Blog/Categories.js b/src/components/Blog/Categories.js index bab04ac4..ca251aad 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 functional component that renders a list of categories. + * + * @param {Object} props - The properties passed to the component. + * @param {Array} props.categories - An array of category slugs. + * @param {string} props.currentSlug - The current category slug being viewed. + * @returns {React.ReactNode} - The rendered list of categories as a div element. + * + * Example: + * + */ const Categories = ({ categories, currentSlug }) => { return (
diff --git a/src/components/Blog/Category.js b/src/components/Blog/Category.js index 8eab7808..b172a816 100644 --- a/src/components/Blog/Category.js +++ b/src/components/Blog/Category.js @@ -2,6 +2,18 @@ import { cx } from "@/src/utils"; import Link from "next/link"; import React from "react"; +/** + * Represents a category component that renders a link with conditional styling based on its active state. + * + * @param {Object} props - The properties for the Category component. + * @param {string} [props.link="#"] - The URL to which the link points. Defaults to '#'. + * @param {string} props.name - The name of the category that will be displayed as the text of the link. + * @param {boolean} [props.active=false] - Indicates whether the category is currently active. If true, it will have a different background and text color. + * @returns {JSX.Element} - A React element representing the Category component. + * + * @example + * + */ 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..474870fd 100644 --- a/src/components/Blog/ViewCounter.js +++ b/src/components/Blog/ViewCounter.js @@ -8,6 +8,17 @@ const ViewCounter = ({ slug, noCount = false, showCount = true }) => { const [views, setViews] = useState(0); useEffect(() => { + /** + * Asynchronously increments the view count of a resource using Supabase RPC. + * + * @async + * @function incrementView + * @param {Object} options - The options object containing necessary parameters. + * @param {string} options.slug - The slug text used as an identifier for the resource whose view count needs to be incremented. + * @returns {Promise} A promise that resolves when the operation is complete, or rejects if an error occurs. + * + * @throws {Error} Throws an error if there is an issue with the Supabase RPC call or if an unexpected error occurs during the process. + */ const incrementView = async () => { try { let { error } = await supabase.rpc("increment", { @@ -32,6 +43,14 @@ const ViewCounter = ({ slug, noCount = false, showCount = true }) => { }, [slug, noCount]); useEffect(() => { + /** + * Asynchronously increments the view count for a specific item based on its slug. + * + * @async + * @function + * @param {string} slug - The unique identifier (slug) of the item whose views need to be incremented. + * @throws {Error} If an error occurs while executing the query or processing the response. + */ 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..da57df00 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 submitting project inquiries. + * + * @returns {JSX.Element} - The rendered contact form. + */ export default function ContactForm() { 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/Contact/LottieAnimation.js b/src/components/Contact/LottieAnimation.js index 6f6019e7..5a900326 100644 --- a/src/components/Contact/LottieAnimation.js +++ b/src/components/Contact/LottieAnimation.js @@ -3,6 +3,12 @@ import React from 'react'; import { DotLottiePlayer } from '@dotlottie/react-player'; import '@dotlottie/react-player/dist/index.css'; +/** + * A React component that renders a Lottie animation using the DotLottiePlayer component. + * + * @function + * @returns {JSX.Element} - A JSX element representing the Lottie animation player. + */ const LottieAnimation = () => { return ( + */ const Tag = ({ link = "#", name, ...props }) => { return ( { 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/Header/Logo.js b/src/components/Header/Logo.js index 7cf904ce..5993be86 100644 --- a/src/components/Header/Logo.js +++ b/src/components/Header/Logo.js @@ -2,6 +2,12 @@ import Image from "next/image" import Link from "next/link" import profileImg from "@/public/profile-img.png" +/** + * Renders a logo component that includes a link to the homepage. + * The logo consists of an image with a border and a text label. + * + * @returns {JSX.Element} - A React JSX element representing the logo. + */ const Logo = () => { return ( diff --git a/src/components/Header/index.js b/src/components/Header/index.js index c04fe9bd..6fabc5a6 100644 --- a/src/components/Header/index.js +++ b/src/components/Header/index.js @@ -7,11 +7,25 @@ import { useThemeSwitch } from "../Hooks/useThemeSwitch"; import { useState } from "react"; import { cx } from "@/src/utils"; +/** + * A functional component that represents the header of a web page. It includes navigation links, a theme switcher button, and social media icons. + * + * @returns {JSX.Element} - The rendered JSX for the Header component. + */ const Header = () => { const [mode, setMode] = useThemeSwitch(); const [click, setClick] = useState(false); +/** + * Toggles the state of 'click'. + * + * @function toggle + * @returns {undefined} - This function does not return any value. + * + * Example usage: + * toggle(); + */ const toggle = () =>{ setClick(!click) } diff --git a/src/components/Home/FeaturedPosts.js b/src/components/Home/FeaturedPosts.js index 5d0056a2..e4128e6a 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 displays featured posts from a list of blogs. + * + * @param {Object} props - The component's props. + * @param {Array} props.blogs - An array of blog objects to be displayed as featured posts. + * @returns {JSX.Element} - The rendered 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..8ce0d8ea 100644 --- a/src/components/Home/HomeCoverSection.js +++ b/src/components/Home/HomeCoverSection.js @@ -5,6 +5,17 @@ import React from 'react' import Tag from '../Elements/Tag'; import { slug } from 'github-slugger'; +/** + * React component that displays the home cover section with the most recent blog post. + * + * @param {Object} props - The properties passed to the component. + * @param {Array} props.blogs - An array of blog objects to be sorted and displayed. + * + * @returns {JSX.Element} The rendered JSX element for the home cover section. + * + * @example + * + */ const HomeCoverSection = ({blogs}) => { const sortedBlogs = sortBlogs(blogs); diff --git a/src/components/Home/RecentPosts.js b/src/components/Home/RecentPosts.js index 9e715f9a..4880e996 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"; +/** + * React component that renders a section displaying recent blog posts. + * + * @param {Object} props - The component props. + * @param {Array} props.blogs - An array of blog objects to be displayed. + * @returns {JSX.Element} - 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..b7ccff92 100644 --- a/src/components/Hooks/useThemeSwitch.js +++ b/src/components/Hooks/useThemeSwitch.js @@ -2,10 +2,20 @@ import { useEffect, useState } from "react"; +/** + * Custom hook for managing theme switching between dark and light modes. + * + * @returns {Array} An array containing the current mode ('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 light and dark modes. + * + * @param {string} theme - The theme to apply. Must be either "dark" or "light". + */ const toggleTheme = (theme) => { if (theme === "dark") { document.documentElement.classList.add("dark"); @@ -15,6 +25,11 @@ export function useThemeSwitch() { window.localStorage.setItem(storageKey, theme); }; + /** + * Retrieves the user's preference from local storage or determines it based on the system's color scheme. + * + * @returns {string} The user's preference, either "dark" or "light". + */ const getUserPreference = () => { const userPref = window.localStorage.getItem(storageKey); if (userPref) { @@ -27,6 +42,9 @@ export function useThemeSwitch() { useEffect(() => { const mediaQuery = window.matchMedia(preferDarkQuery); + /** + * Handles language change by updating user preferences, setting mode, and toggling theme. + */ const handleChange = () => { const newMode = getUserPreference(); setMode(newMode); diff --git a/src/components/Icons.js b/src/components/Icons.js index f80ab3cc..64c94149 100644 --- a/src/components/Icons.js +++ b/src/components/Icons.js @@ -1,6 +1,25 @@ import React from "react"; import { cx } from "../utils"; +/** + * Renders a Sun icon with animated transitions. + * + * @param {Object} props - The component props. + * @param {string} [props.className] - Additional CSS classes to apply to the SVG element. + * @returns {JSX.Element} - The rendered SunIcon component. + * + * @example + * import React from 'react'; + * import { SunIcon } from './path/to/SunIcon'; + * + * const App = () => ( + *
+ * + *
+ * ); + * + * export default App; + */ export const SunIcon = ({ className, ...rest }) => ( ( ); +/** + * Renders a LinkedIn icon as an SVG. + * + * @param {Object} props - The component's properties. + * @param {string} [props.className] - Additional CSS classes to apply to the icon. + * @returns {JSX.Element} - The rendered LinkedIn icon. + * + * Example usage: + * + */ export const LinkedinIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component that renders a Twitter icon. + * + * @param {Object} props - The component's props. + * @param {string} [props.className] - Additional class names to apply to the SVG element. + * @returns {JSX.Element} - The rendered Twitter icon as an SVG element. + * + * Example usage: + * + */ export const TwitterIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * A React component to render the GitHub icon. + * + * @param {Object} props - The properties for the GithubIcon component. + * @param {string} [props.className] - Additional CSS class names to apply. + * @returns {JSX.Element} - The rendered GithubIcon element. + * + * @example + * + */ export const GithubIcon = ({ className, ...rest }) => { return ( { ); }; +/** + * Represents a Dribbble icon component. + * + * @param {Object} props - The component props. + * @param {string} [props.className] - Additional CSS classes to apply to the icon. + * @returns {JSX.Element} - A React SVG 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 - The array of blog objects to be sorted. Each object should have a 'publishedAt' property in ISO format. + * @returns {Array} - The sorted array of blog objects. + * @throws {Error} - If the input is not an array or if any blog object does not contain a valid 'publishedAt' property in ISO format. + * + * @example + * const blogs = [ + * { title: 'Blog 1', publishedAt: '2023-04-01T12:00:00Z' }, + * { title: 'Blog 2', publishedAt: '2023-04-02T12:00:00Z' } + * ]; + * const sortedBlogs = sortBlogs(blogs); + * console.log(sortedBlogs); // Output will be the blogs array sorted by published date in descending order. + */ export const sortBlogs = (blogs) => { return blogs .slice()