Github Widget

Rendered Component

Loading component...

Packages

npm install framer-motion
npm install @fortawesome/react-fontawesome
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/free-brands-svg-icons
yarn add framer-motion
yarn add @fortawesome/react-fontawesome
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/free-brands-svg-icons

Code

Details

The Terminal Window component is a fun and interactive way to display text-based information. It emulates the look and feel of a retro terminal interface, complete with a blinking cursor and customizable themes.

Usage

Import the TerminalWindow component and provide it with the necessary text content and styling options.

Examples

  • Homepage weather display
  • Travel app destination weather
  • Smart home dashboard weather widget

Code


  import React, { useState, useEffect } from 'react';
  import { motion } from 'framer-motion';
  import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
  import {
    faGithub,
    faStar,
    faCodeBranch,
    faSpinner,
  } from '@fortawesome/free-solid-svg-icons';
  import { faGithubAlt } from '@fortawesome/free-brands-svg-icons';

  const GitHubStats = ({ username }) => {
    const [userData, setUserData] = useState(null);
    const [repoData, setRepoData] = useState(null);
    const [loading, setLoading] = useState({ user: true, repo: true });
    const [error, setError] = useState(null);

    useEffect(() => {
      const fetchData = async () => {
        try {
          const userResponse = await fetch(
            `https://api.github.com/users/${username}`
          );
          if (!userResponse.ok) {
            throw new Error('Failed to fetch user data');
          }
          const userData = await userResponse.json();
          setUserData(userData);
          setLoading((prev) => ({ ...prev, user: false }));

          const reposResponse = await fetch(
            `https://api.github.com/users/${username}/repos?sort=stars&per_page=100`
          );
          if (!reposResponse.ok) {
            throw new Error('Failed to fetch repo data');
          }
          const reposData = await reposResponse.json();
          const pm2Dashboard = reposData.find(
            (repo) => repo.name.toLowerCase() === 'pm2-ui'
          );
          setRepoData(pm2Dashboard);
          setLoading((prev) => ({ ...prev, repo: false }));
        } catch (error) {
          console.error('Error fetching GitHub data:', error);
          setError(error.message);
          setLoading({ user: false, repo: false });
        }
      };
      fetchData();
    }, [username]);

    const SpinnerIcon = () => (
      <FontAwesomeIcon icon={faSpinner} spin className='text-blue-400' />
    );

    return (
      <div className='flex bg-zinc-900 rounded-xl'>
        <div className='flex flex-col items-center justify-center w-1/2 px-4'>
          <FontAwesomeIcon
            icon={faGithubAlt}
            className='mr-2 w-6 h-6 text-zinc-200'
          />
          <h2 className='text-2xl text-white font-semibold mb-2 flex items-center'>
            Github Stats
          </h2>
        </div>
        <motion.div
          initial={{ opacity: 0, y: 20 }}
          animate={{ opacity: 1, y: 0 }}
          transition={{ duration: 0.5 }}
          className='bg-zinc-800 w-full p-4 rounded-xl shadow-lg text-zinc-200'
        >
          {error ? (
            <div className='text-red-500'>Error: {error}</div>
          ) : (
            <div className=' p-3 rounded flex justify-around gap-6'>
              <div>
                <p className='text-gray-400'>Followers</p>
                <p className='text-2xl font-bold'>
                  {loading.user ? (
                    <FontAwesomeIcon icon={faSpinner} className='animate-spin' />
                  ) : (
                    userData?.followers
                  )}
                </p>
              </div>
              <div>
                {loading.repo ? (
                  <FontAwesomeIcon icon={faSpinner} className='animate-spin' />
                ) : (
                  <a
                    href={repoData?.html_url}
                    target='_blank'
                    rel='noopener noreferrer'
                    className='hover:text-blue-400 text-xl font-bold'
                  >
                    {repoData?.name}
                  </a>
                )}
                <div className='flex items-center mt-1 text-sm text-gray-400'>
                  <span className='mr-3'>
                    <FontAwesomeIcon icon={faStar} className='mr-1 w-5 h-5' />
                    {loading.repo ? (
                      <FontAwesomeIcon
                        icon={faSpinner}
                        className='animate-spin'
                      />
                    ) : (
                      repoData?.stargazers_count
                    )}
                  </span>
                  <span>
                    <FontAwesomeIcon
                      icon={faCodeBranch}
                      className='mr-1 w-5 h-5'
                    />
                    {loading.repo ? (
                      <FontAwesomeIcon
                        icon={faSpinner}
                        className='animate-spin'
                      />
                    ) : (
                      repoData?.forks_count
                    )}
                  </span>
                </div>
              </div>
            </div>
          )}
        </motion.div>
      </div>
    );
  };
  export default GitHubStats;