mirror of
https://github.com/NohamR/gitprofile.git
synced 2026-05-25 04:17:13 +00:00
Migrate from redux to context
This commit is contained in:
@@ -1,16 +1,17 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import { fallbackImage, skeleton } from "../helpers/utils";
|
||||
import LazyImage from "./LazyImage";
|
||||
import PropTypes from 'prop-types';
|
||||
import { useContext } from "react";
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
|
||||
const AvatarCard = () => {
|
||||
const profile = useSelector(state => state.profile);
|
||||
const loading = useSelector(state => state.loading);
|
||||
const AvatarCard = (props) => {
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
return (
|
||||
<div className="card shadow-lg compact bg-base-100">
|
||||
<div className="grid place-items-center py-8">
|
||||
{
|
||||
loading ? (
|
||||
(loading || !props.profile) ? (
|
||||
<div className="avatar opacity-90">
|
||||
<div className="mb-8 rounded-full w-32 h-32">
|
||||
{
|
||||
@@ -27,8 +28,8 @@ const AvatarCard = () => {
|
||||
<div className="mb-8 rounded-full w-32 h-32 ring ring-primary ring-offset-base-100 ring-offset-2">
|
||||
{
|
||||
<LazyImage
|
||||
src={profile.avatar ? profile.avatar : fallbackImage}
|
||||
alt={profile.name}
|
||||
src={props.profile.avatar ? props.profile.avatar : fallbackImage}
|
||||
alt={props.profile.name}
|
||||
placeholder={
|
||||
skeleton({
|
||||
width: 'w-full',
|
||||
@@ -45,16 +46,16 @@ const AvatarCard = () => {
|
||||
<div className="text-center mx-auto px-8">
|
||||
<h5 className="font-bold text-2xl">
|
||||
{
|
||||
loading ? (
|
||||
(loading || !props.profile) ? (
|
||||
skeleton({ width: 'w-48', height: 'h-8' })
|
||||
) : <span className="opacity-70">{profile.name}</span>
|
||||
) : <span className="opacity-70">{props.profile.name}</span>
|
||||
}
|
||||
</h5>
|
||||
<div className="mt-3 text-base-content text-opacity-60">
|
||||
{
|
||||
loading ? (
|
||||
(loading || !props.profile) ? (
|
||||
skeleton({ width: 'w-48', height: 'h-5' })
|
||||
) : profile.bio
|
||||
) : props.profile.bio
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -63,4 +64,8 @@ const AvatarCard = () => {
|
||||
)
|
||||
}
|
||||
|
||||
AvatarCard.propTypes = {
|
||||
profile: PropTypes.object
|
||||
}
|
||||
|
||||
export default AvatarCard;
|
||||
@@ -1,9 +1,9 @@
|
||||
import { getDevtoArticle, getMediumArticle } from "article-api";
|
||||
import moment from "moment";
|
||||
import { Fragment, useEffect, useState } from "react";
|
||||
import { Fragment, useContext, useEffect, useState } from "react";
|
||||
import { CgHashtag } from 'react-icons/cg';
|
||||
import { useSelector } from "react-redux";
|
||||
import config from "../config";
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
import { ga, skeleton } from "../helpers/utils";
|
||||
import LazyImage from "./LazyImage";
|
||||
|
||||
@@ -23,7 +23,7 @@ const displaySection = () => {
|
||||
|
||||
const Blog = () => {
|
||||
const [articles, setArticles] = useState(null);
|
||||
const loading = useSelector(state => state.loading);
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (displaySection()) {
|
||||
|
||||
@@ -5,13 +5,14 @@ import { GrLinkedinOption } from 'react-icons/gr';
|
||||
import { CgDribbble } from 'react-icons/cg';
|
||||
import { RiPhoneFill } from 'react-icons/ri';
|
||||
import { FaBehanceSquare, FaBuilding, FaDev, FaFacebook, FaGlobe } from 'react-icons/fa';
|
||||
import { useSelector } from 'react-redux';
|
||||
import config from '../config';
|
||||
import { skeleton } from '../helpers/utils';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useContext } from 'react';
|
||||
import { LoadingContext } from '../contexts/LoadingContext';
|
||||
|
||||
const Details = () => {
|
||||
const profile = useSelector(state => state.profile);
|
||||
const loading = useSelector(state => state.loading);
|
||||
const Details = (props) => {
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const renderSkeleton = () => {
|
||||
let array = [];
|
||||
@@ -34,24 +35,24 @@ const Details = () => {
|
||||
<div className="card-body">
|
||||
<ul className="menu row-span-3 bg-base-100 text-base-content text-opacity-60">
|
||||
{
|
||||
loading ? renderSkeleton() : (
|
||||
(loading || !props.profile) ? renderSkeleton() : (
|
||||
<>
|
||||
{
|
||||
profile && profile.location && (
|
||||
props.profile.location && (
|
||||
<li>
|
||||
<span>
|
||||
<MdLocationOn className="mr-2" />
|
||||
{profile.location}
|
||||
{props.profile.location}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
}
|
||||
{
|
||||
profile && profile.company && (
|
||||
props.profile.company && (
|
||||
<li>
|
||||
<span>
|
||||
<FaBuilding className="mr-2" />
|
||||
{profile.company}
|
||||
{props.profile.company}
|
||||
</span>
|
||||
</li>
|
||||
)
|
||||
@@ -247,4 +248,8 @@ const Details = () => {
|
||||
)
|
||||
}
|
||||
|
||||
Details.propTypes = {
|
||||
profile: PropTypes.object
|
||||
}
|
||||
|
||||
export default Details;
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import config from "../config";
|
||||
import { GoPrimitiveDot } from 'react-icons/go';
|
||||
import { skeleton } from "../helpers/utils";
|
||||
import { useContext } from "react";
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
|
||||
const Education = () => {
|
||||
const loading = useSelector(state => state.loading);
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const renderSkeleton = () => {
|
||||
let array = [];
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import config from "../config";
|
||||
import { GoPrimitiveDot } from 'react-icons/go';
|
||||
import { skeleton } from "../helpers/utils";
|
||||
import { useContext } from "react";
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
|
||||
const Experience = () => {
|
||||
const loading = useSelector(state => state.loading);
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const renderSkeleton = () => {
|
||||
let array = [];
|
||||
@@ -44,9 +45,11 @@ const Experience = () => {
|
||||
<li>
|
||||
<div className="pb-0-important mx-3">
|
||||
<h5 className="card-title">
|
||||
{loading ? skeleton({width: 'w-32', height: 'h-8'}) : (
|
||||
<span className="opacity-70">Experience</span>
|
||||
)}
|
||||
{
|
||||
loading ? skeleton({width: 'w-32', height: 'h-8'}) : (
|
||||
<span className="opacity-70">Experience</span>
|
||||
)
|
||||
}
|
||||
</h5>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
import React, { Fragment } from 'react';
|
||||
import React, { Fragment, useContext } from 'react';
|
||||
import { Helmet } from "react-helmet-async";
|
||||
import { useSelector } from 'react-redux';
|
||||
import config from '../config';
|
||||
import { isThemeDarkish } from '../helpers/utils';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ThemeContext } from '../contexts/ThemeContext';
|
||||
|
||||
const MetaTags = () => {
|
||||
const profile = useSelector(state => state.profile);
|
||||
const theme = useSelector(state => state.theme);
|
||||
const MetaTags = (props) => {
|
||||
const [theme] = useContext(ThemeContext);
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{
|
||||
profile && (
|
||||
props.profile && (
|
||||
<Helmet>
|
||||
{
|
||||
config.googleAnalytics.id && (
|
||||
@@ -33,25 +33,25 @@ const MetaTags = () => {
|
||||
</script>
|
||||
)
|
||||
}
|
||||
<title>Portfolio of {profile.name}</title>
|
||||
<title>Portfolio of {props.profile.name}</title>
|
||||
<meta name="theme-color" content={isThemeDarkish(theme) ? '#000000' : '#ffffff'}/>
|
||||
|
||||
<meta name="description" content={profile.bio} />
|
||||
<meta name="description" content={props.profile.bio} />
|
||||
|
||||
<meta itemprop="name" content={`Portfolio of ${profile.name}`} />
|
||||
<meta itemprop="description" content={profile.bio} />
|
||||
<meta itemprop="image" content={profile.avatar} />
|
||||
<meta itemprop="name" content={`Portfolio of ${props.profile.name}`} />
|
||||
<meta itemprop="description" content={props.profile.bio} />
|
||||
<meta itemprop="image" content={props.profile.avatar} />
|
||||
|
||||
<meta property="og:url" content={typeof config.social.website !== 'undefined' ? config.social.website : ''} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content={`Portfolio of ${profile.name}`} />
|
||||
<meta property="og:description" content={profile.bio} />
|
||||
<meta property="og:image" content={profile.avatar} />
|
||||
<meta property="og:title" content={`Portfolio of ${props.profile.name}`} />
|
||||
<meta property="og:description" content={props.profile.bio} />
|
||||
<meta property="og:image" content={props.profile.avatar} />
|
||||
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content={`Portfolio of ${profile.name}`} />
|
||||
<meta name="twitter:description" content={profile.bio} />
|
||||
<meta name="twitter:image" content={profile.avatar} />
|
||||
<meta name="twitter:title" content={`Portfolio of ${props.profile.name}`} />
|
||||
<meta name="twitter:description" content={props.profile.bio} />
|
||||
<meta name="twitter:image" content={props.profile.avatar} />
|
||||
</Helmet>
|
||||
)
|
||||
}
|
||||
@@ -59,4 +59,8 @@ const MetaTags = () => {
|
||||
)
|
||||
}
|
||||
|
||||
MetaTags.propTypes = {
|
||||
profile: PropTypes.object
|
||||
}
|
||||
|
||||
export default MetaTags;
|
||||
@@ -1,12 +1,12 @@
|
||||
import { Fragment } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { Fragment, useContext } from "react";
|
||||
import { ga, languageColor, skeleton } from "../helpers/utils";
|
||||
import { AiOutlineStar, AiOutlineFork } from 'react-icons/ai';
|
||||
import config from "../config";
|
||||
import PropTypes from 'prop-types';
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
|
||||
const Project = () => {
|
||||
const loading = useSelector(state => state.loading);
|
||||
const repo = useSelector(state => state.repo);
|
||||
const Project = (props) => {
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const renderSkeleton = () => {
|
||||
let array = [];
|
||||
@@ -51,7 +51,7 @@ const Project = () => {
|
||||
}
|
||||
|
||||
const renderProjects = () => {
|
||||
return repo.map((item, index) => (
|
||||
return props.repo.map((item, index) => (
|
||||
<div
|
||||
className="card shadow-lg compact bg-base-100 cursor-pointer"
|
||||
key={index}
|
||||
@@ -146,7 +146,7 @@ const Project = () => {
|
||||
</div>
|
||||
<div className="col-span-2">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
{(loading || !repo) ? renderSkeleton() : renderProjects()}
|
||||
{(loading || !props.repo) ? renderSkeleton() : renderProjects()}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -155,4 +155,8 @@ const Project = () => {
|
||||
)
|
||||
}
|
||||
|
||||
Project.propTypes = {
|
||||
repo: PropTypes.array
|
||||
}
|
||||
|
||||
export default Project;
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useSelector } from "react-redux";
|
||||
import { useContext } from "react";
|
||||
import config from "../config";
|
||||
import { LoadingContext } from "../contexts/LoadingContext";
|
||||
import { skeleton } from "../helpers/utils";
|
||||
|
||||
const Skill = () => {
|
||||
const loading = useSelector(state => state.loading);
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const renderSkeleton = () => {
|
||||
let array = [];
|
||||
@@ -26,9 +27,11 @@ const Skill = () => {
|
||||
<div className="card-body">
|
||||
<div className="mx-3">
|
||||
<h5 className="card-title">
|
||||
{loading ? skeleton({width: 'w-32', height: 'h-8'}) : (
|
||||
<span className="opacity-70">Tech Stack</span>
|
||||
)}
|
||||
{
|
||||
loading ? skeleton({width: 'w-32', height: 'h-8'}) : (
|
||||
<span className="opacity-70">Tech Stack</span>
|
||||
)
|
||||
}
|
||||
</h5>
|
||||
</div>
|
||||
<div className="p-3 flow-root">
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { setTheme } from '../store/slices/themeSlice';
|
||||
import config from '../config';
|
||||
import { skeleton } from '../helpers/utils';
|
||||
import { AiOutlineControl } from 'react-icons/ai';
|
||||
import { useContext } from 'react';
|
||||
import { ThemeContext } from '../contexts/ThemeContext';
|
||||
import { LoadingContext } from '../contexts/LoadingContext';
|
||||
|
||||
const ThemeChanger = () => {
|
||||
const dispatch = useDispatch();
|
||||
const theme = useSelector(state => state.theme);
|
||||
const loading = useSelector(state => state.loading);
|
||||
const [theme, setTheme] = useContext(ThemeContext);
|
||||
const [loading] = useContext(LoadingContext);
|
||||
|
||||
const changeTheme = (e, selectedTheme) => {
|
||||
e.preventDefault();
|
||||
dispatch(setTheme(selectedTheme));
|
||||
document.querySelector('html').setAttribute('data-theme', selectedTheme);
|
||||
localStorage.setItem('ezprofileTheme', selectedTheme);
|
||||
|
||||
setTheme(selectedTheme);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -26,7 +29,9 @@ const ThemeChanger = () => {
|
||||
}
|
||||
</h5>
|
||||
<span className="text-base-content text-opacity-40 capitalize text-sm">
|
||||
{loading ? skeleton({ width: 'w-16', height: 'h-5' }) : (theme === config.themeConfig.default ? 'Default' : theme)}
|
||||
{
|
||||
loading ? skeleton({ width: 'w-16', height: 'h-5' }) : (theme === config.themeConfig.default ? 'Default' : theme)
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex-0">
|
||||
|
||||
Reference in New Issue
Block a user