mirror of
https://github.com/NohamR/gitprofile.git
synced 2026-05-26 04:17:14 +00:00
Remove context for state management
This commit is contained in:
33
src/App.jsx
33
src/App.jsx
@@ -1,8 +1,6 @@
|
|||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { Fragment, useCallback, useContext, useEffect, useState } from 'react';
|
import { Fragment, useCallback, useEffect, useState } from 'react';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { ThemeContext } from './contexts/ThemeContext';
|
|
||||||
import { LoadingContext } from './contexts/LoadingContext';
|
|
||||||
import config from './ezprofile.config';
|
import config from './ezprofile.config';
|
||||||
import HeadTagEditor from './components/head-tag-editor';
|
import HeadTagEditor from './components/head-tag-editor';
|
||||||
import ErrorPage from './components/error-page';
|
import ErrorPage from './components/error-page';
|
||||||
@@ -14,10 +12,11 @@ import Experience from './components/experience';
|
|||||||
import Education from './components/education';
|
import Education from './components/education';
|
||||||
import Project from './components/project';
|
import Project from './components/project';
|
||||||
import Blog from './components/blog';
|
import Blog from './components/blog';
|
||||||
|
import { getInitialTheme } from './helpers/utils';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const { theme } = useContext(ThemeContext);
|
const [theme, setTheme] = useState(getInitialTheme());
|
||||||
const { setLoading } = useContext(LoadingContext);
|
const [loading, setLoading] = useState(true);
|
||||||
const [profile, setProfile] = useState(null);
|
const [profile, setProfile] = useState(null);
|
||||||
const [repo, setRepo] = useState(null);
|
const [repo, setRepo] = useState(null);
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
@@ -108,7 +107,7 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<HeadTagEditor profile={profile} />
|
<HeadTagEditor profile={profile} theme={theme} />
|
||||||
<div className="fade-in h-screen">
|
<div className="fade-in h-screen">
|
||||||
{error ? (
|
{error ? (
|
||||||
<ErrorPage
|
<ErrorPage
|
||||||
@@ -149,18 +148,24 @@ function App() {
|
|||||||
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 rounded-box">
|
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6 rounded-box">
|
||||||
<div className="col-span-1">
|
<div className="col-span-1">
|
||||||
<div className="grid grid-cols-1 gap-6">
|
<div className="grid grid-cols-1 gap-6">
|
||||||
{!config.themeConfig.disableSwitch && <ThemeChanger />}
|
{!config.themeConfig.disableSwitch && (
|
||||||
<AvatarCard profile={profile} />
|
<ThemeChanger
|
||||||
<Details profile={profile} />
|
theme={theme}
|
||||||
<Skill />
|
setTheme={setTheme}
|
||||||
<Experience />
|
loading={loading}
|
||||||
<Education />
|
/>
|
||||||
|
)}
|
||||||
|
<AvatarCard profile={profile} loading={loading} />
|
||||||
|
<Details profile={profile} loading={loading} />
|
||||||
|
<Skill loading={loading} />
|
||||||
|
<Experience loading={loading} />
|
||||||
|
<Education loading={loading} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:col-span-2 col-span-1">
|
<div className="lg:col-span-2 col-span-1">
|
||||||
<div className="grid grid-cols-1 gap-6">
|
<div className="grid grid-cols-1 gap-6">
|
||||||
<Project repo={repo} />
|
<Project repo={repo} loading={loading} />
|
||||||
<Blog />
|
<Blog loading={loading} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,16 +1,12 @@
|
|||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useContext } from 'react';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
import LazyImage from '../lazy-image';
|
import LazyImage from '../lazy-image';
|
||||||
|
|
||||||
const AvatarCard = (props) => {
|
const AvatarCard = ({ profile, loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="card shadow-lg compact bg-base-100">
|
<div className="card shadow-lg compact bg-base-100">
|
||||||
<div className="grid place-items-center py-8">
|
<div className="grid place-items-center py-8">
|
||||||
{loading || !props.profile ? (
|
{loading || !profile ? (
|
||||||
<div className="avatar opacity-90">
|
<div className="avatar opacity-90">
|
||||||
<div className="mb-8 rounded-full w-32 h-32">
|
<div className="mb-8 rounded-full w-32 h-32">
|
||||||
{skeleton({
|
{skeleton({
|
||||||
@@ -25,10 +21,8 @@ const AvatarCard = (props) => {
|
|||||||
<div className="mb-8 rounded-full w-32 h-32 ring ring-primary ring-offset-base-100 ring-offset-2">
|
<div className="mb-8 rounded-full w-32 h-32 ring ring-primary ring-offset-base-100 ring-offset-2">
|
||||||
{
|
{
|
||||||
<LazyImage
|
<LazyImage
|
||||||
src={
|
src={profile.avatar ? profile.avatar : fallbackImage}
|
||||||
props.profile.avatar ? props.profile.avatar : fallbackImage
|
alt={profile.name}
|
||||||
}
|
|
||||||
alt={props.profile.name}
|
|
||||||
placeholder={skeleton({
|
placeholder={skeleton({
|
||||||
width: 'w-full',
|
width: 'w-full',
|
||||||
height: 'h-full',
|
height: 'h-full',
|
||||||
@@ -41,16 +35,16 @@ const AvatarCard = (props) => {
|
|||||||
)}
|
)}
|
||||||
<div className="text-center mx-auto px-8">
|
<div className="text-center mx-auto px-8">
|
||||||
<h5 className="font-bold text-2xl">
|
<h5 className="font-bold text-2xl">
|
||||||
{loading || !props.profile ? (
|
{loading || !profile ? (
|
||||||
skeleton({ width: 'w-48', height: 'h-8' })
|
skeleton({ width: 'w-48', height: 'h-8' })
|
||||||
) : (
|
) : (
|
||||||
<span className="opacity-70">{props.profile.name}</span>
|
<span className="opacity-70">{profile.name}</span>
|
||||||
)}
|
)}
|
||||||
</h5>
|
</h5>
|
||||||
<div className="mt-3 text-base-content text-opacity-60">
|
<div className="mt-3 text-base-content text-opacity-60">
|
||||||
{loading || !props.profile
|
{loading || !profile
|
||||||
? skeleton({ width: 'w-48', height: 'h-5' })
|
? skeleton({ width: 'w-48', height: 'h-5' })
|
||||||
: props.profile.bio}
|
: profile.bio}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import { getDevtoArticle, getMediumArticle } from 'article-api';
|
import { getDevtoArticle, getMediumArticle } from 'article-api';
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
import { Fragment, useContext, useEffect, useState } from 'react';
|
import { Fragment, useEffect, useState } from 'react';
|
||||||
import { CgHashtag } from 'react-icons/cg';
|
import { CgHashtag } from 'react-icons/cg';
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
import { ga, skeleton } from '../../helpers/utils';
|
import { ga, skeleton } from '../../helpers/utils';
|
||||||
import LazyImage from '../lazy-image';
|
import LazyImage from '../lazy-image';
|
||||||
@@ -21,9 +20,8 @@ const displaySection = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const Blog = () => {
|
const Blog = ({loading}) => {
|
||||||
const [articles, setArticles] = useState(null);
|
const [articles, setArticles] = useState(null);
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (displaySection()) {
|
if (displaySection()) {
|
||||||
|
|||||||
@@ -12,8 +12,6 @@ import {
|
|||||||
FaGlobe,
|
FaGlobe,
|
||||||
} from 'react-icons/fa';
|
} from 'react-icons/fa';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { useContext } from 'react';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
|
|
||||||
@@ -31,9 +29,7 @@ const ListItem = ({ icon, title, value, link }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const Details = (props) => {
|
const Details = ({ profile, loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
let array = [];
|
let array = [];
|
||||||
for (let index = 0; index < 4; index++) {
|
for (let index = 0; index < 4; index++) {
|
||||||
@@ -53,22 +49,22 @@ const Details = (props) => {
|
|||||||
return (
|
return (
|
||||||
<div className="card shadow-lg compact bg-base-100">
|
<div className="card shadow-lg compact bg-base-100">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{loading || !props.profile ? (
|
{loading || !profile ? (
|
||||||
renderSkeleton()
|
renderSkeleton()
|
||||||
) : (
|
) : (
|
||||||
<div className="bg-base-100 text-base-content text-opacity-60">
|
<div className="bg-base-100 text-base-content text-opacity-60">
|
||||||
{props.profile.location && (
|
{profile.location && (
|
||||||
<ListItem
|
<ListItem
|
||||||
icon={<MdLocationOn className="mr-2" />}
|
icon={<MdLocationOn className="mr-2" />}
|
||||||
title="Based on"
|
title="Based on"
|
||||||
value={props.profile.location}
|
value={profile.location}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{props.profile.company && (
|
{profile.company && (
|
||||||
<ListItem
|
<ListItem
|
||||||
icon={<FaBuilding className="mr-2" />}
|
icon={<FaBuilding className="mr-2" />}
|
||||||
title="Company"
|
title="Company"
|
||||||
value={props.profile.company}
|
value={profile.company}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<ListItem
|
<ListItem
|
||||||
@@ -116,7 +112,7 @@ const Details = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{/* <ul className="menu bg-base-100 text-base-content text-opacity-60">
|
{/* <ul className="menu bg-base-100 text-base-content text-opacity-60">
|
||||||
{loading || !props.profile ? (
|
{loading || !profile ? (
|
||||||
renderSkeleton()
|
renderSkeleton()
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { GoPrimitiveDot } from 'react-icons/go';
|
import { GoPrimitiveDot } from 'react-icons/go';
|
||||||
import { useContext } from 'react';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
|
|
||||||
const Education = () => {
|
const Education = ({ loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
let array = [];
|
let array = [];
|
||||||
for (let index = 0; index < 2; index++) {
|
for (let index = 0; index < 2; index++) {
|
||||||
|
|||||||
@@ -1,12 +1,8 @@
|
|||||||
import { GoPrimitiveDot } from 'react-icons/go';
|
import { GoPrimitiveDot } from 'react-icons/go';
|
||||||
import { useContext } from 'react';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
|
|
||||||
const Experience = () => {
|
const Experience = ({ loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
let array = [];
|
let array = [];
|
||||||
for (let index = 0; index < 2; index++) {
|
for (let index = 0; index < 2; index++) {
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
import { Fragment, useContext } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { Helmet } from 'react-helmet-async';
|
import { Helmet } from 'react-helmet-async';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { ThemeContext } from '../../contexts/ThemeContext';
|
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
import { isThemeDarkish } from '../../helpers/utils';
|
import { isThemeDarkish } from '../../helpers/utils';
|
||||||
|
|
||||||
const HeadTagEditor = (props) => {
|
const HeadTagEditor = ({ profile, theme }) => {
|
||||||
const { theme } = useContext(ThemeContext);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{props.profile && (
|
{profile && (
|
||||||
<Helmet>
|
<Helmet>
|
||||||
{config.googleAnalytics?.id && (
|
{config.googleAnalytics?.id && (
|
||||||
<script
|
<script
|
||||||
@@ -26,20 +23,17 @@ const HeadTagEditor = (props) => {
|
|||||||
gtag('config', '${config.googleAnalytics.id}');`}
|
gtag('config', '${config.googleAnalytics.id}');`}
|
||||||
</script>
|
</script>
|
||||||
)}
|
)}
|
||||||
<title>Portfolio of {props.profile.name}</title>
|
<title>Portfolio of {profile.name}</title>
|
||||||
<meta
|
<meta
|
||||||
name="theme-color"
|
name="theme-color"
|
||||||
content={isThemeDarkish(theme) ? '#000000' : '#ffffff'}
|
content={isThemeDarkish(theme) ? '#000000' : '#ffffff'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<meta name="description" content={props.profile.bio} />
|
<meta name="description" content={profile.bio} />
|
||||||
|
|
||||||
<meta
|
<meta itemprop="name" content={`Portfolio of ${profile.name}`} />
|
||||||
itemprop="name"
|
<meta itemprop="description" content={profile.bio} />
|
||||||
content={`Portfolio of ${props.profile.name}`}
|
<meta itemprop="image" content={profile.avatar} />
|
||||||
/>
|
|
||||||
<meta itemprop="description" content={props.profile.bio} />
|
|
||||||
<meta itemprop="image" content={props.profile.avatar} />
|
|
||||||
|
|
||||||
<meta
|
<meta
|
||||||
property="og:url"
|
property="og:url"
|
||||||
@@ -50,20 +44,14 @@ const HeadTagEditor = (props) => {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<meta property="og:type" content="website" />
|
<meta property="og:type" content="website" />
|
||||||
<meta
|
<meta property="og:title" content={`Portfolio of ${profile.name}`} />
|
||||||
property="og:title"
|
<meta property="og:description" content={profile.bio} />
|
||||||
content={`Portfolio of ${props.profile.name}`}
|
<meta property="og:image" content={profile.avatar} />
|
||||||
/>
|
|
||||||
<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:card" content="summary_large_image" />
|
||||||
<meta
|
<meta name="twitter:title" content={`Portfolio of ${profile.name}`} />
|
||||||
name="twitter:title"
|
<meta name="twitter:description" content={profile.bio} />
|
||||||
content={`Portfolio of ${props.profile.name}`}
|
<meta name="twitter:image" content={profile.avatar} />
|
||||||
/>
|
|
||||||
<meta name="twitter:description" content={props.profile.bio} />
|
|
||||||
<meta name="twitter:image" content={props.profile.avatar} />
|
|
||||||
</Helmet>
|
</Helmet>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@@ -1,13 +1,10 @@
|
|||||||
import { Fragment, useContext } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { AiOutlineStar, AiOutlineFork } from 'react-icons/ai';
|
import { AiOutlineStar, AiOutlineFork } from 'react-icons/ai';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
import { ga, languageColor, skeleton } from '../../helpers/utils';
|
import { ga, languageColor, skeleton } from '../../helpers/utils';
|
||||||
|
|
||||||
const Project = (props) => {
|
const Project = ({ repo, loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
let array = [];
|
let array = [];
|
||||||
for (let index = 0; index < config.github.limit; index++) {
|
for (let index = 0; index < config.github.limit; index++) {
|
||||||
@@ -55,7 +52,7 @@ const Project = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const renderProjects = () => {
|
const renderProjects = () => {
|
||||||
return props.repo.map((item, index) => (
|
return repo.map((item, index) => (
|
||||||
<div
|
<div
|
||||||
className="card shadow-lg compact bg-base-100 cursor-pointer"
|
className="card shadow-lg compact bg-base-100 cursor-pointer"
|
||||||
key={index}
|
key={index}
|
||||||
@@ -163,7 +160,7 @@ const Project = (props) => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-span-2">
|
<div className="col-span-2">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
{loading || !props.repo ? renderSkeleton() : renderProjects()}
|
{loading || !repo ? renderSkeleton() : renderProjects()}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,11 +1,7 @@
|
|||||||
import { useContext } from 'react';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
|
|
||||||
const Skill = () => {
|
const Skill = ({ loading }) => {
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
const renderSkeleton = () => {
|
const renderSkeleton = () => {
|
||||||
let array = [];
|
let array = [];
|
||||||
for (let index = 0; index < 12; index++) {
|
for (let index = 0; index < 12; index++) {
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
import { AiOutlineControl } from 'react-icons/ai';
|
import { AiOutlineControl } from 'react-icons/ai';
|
||||||
import { useContext } from 'react';
|
|
||||||
import { ThemeContext } from '../../contexts/ThemeContext';
|
|
||||||
import { LoadingContext } from '../../contexts/LoadingContext';
|
|
||||||
import { skeleton } from '../../helpers/utils';
|
import { skeleton } from '../../helpers/utils';
|
||||||
import config from '../../ezprofile.config';
|
import config from '../../ezprofile.config';
|
||||||
|
|
||||||
const ThemeChanger = () => {
|
const ThemeChanger = ({ theme, setTheme, loading }) => {
|
||||||
const { theme, setTheme } = useContext(ThemeContext);
|
|
||||||
const { loading } = useContext(LoadingContext);
|
|
||||||
|
|
||||||
console.log(theme);
|
|
||||||
|
|
||||||
const changeTheme = (e, selectedTheme) => {
|
const changeTheme = (e, selectedTheme) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
document.querySelector('html').setAttribute('data-theme', selectedTheme);
|
document.querySelector('html').setAttribute('data-theme', selectedTheme);
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
import { createContext, useState } from 'react';
|
|
||||||
|
|
||||||
const initialValue = true;
|
|
||||||
|
|
||||||
export const LoadingContext = createContext();
|
|
||||||
|
|
||||||
export const LoadingProvider = (props) => {
|
|
||||||
const [loading, setLoading] = useState(initialValue);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<LoadingContext.Provider value={[loading, setLoading]}>
|
|
||||||
{props.children}
|
|
||||||
</LoadingContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import { createContext, useState } from 'react';
|
|
||||||
import { getInitialTheme } from '../helpers/utils';
|
|
||||||
|
|
||||||
const initialValue = getInitialTheme();
|
|
||||||
|
|
||||||
export const ThemeContext = createContext();
|
|
||||||
|
|
||||||
export const ThemeProvider = (props) => {
|
|
||||||
const [theme, setTheme] = useState(initialValue);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ThemeContext.Provider value={[theme, setTheme]}>
|
|
||||||
{props.children}
|
|
||||||
</ThemeContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@@ -2,19 +2,13 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import { ThemeProvider } from './contexts/ThemeContext';
|
|
||||||
import { LoadingProvider } from './contexts/LoadingContext';
|
|
||||||
import { HelmetProvider } from 'react-helmet-async';
|
import { HelmetProvider } from 'react-helmet-async';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<ThemeProvider>
|
|
||||||
<LoadingProvider>
|
|
||||||
<HelmetProvider>
|
<HelmetProvider>
|
||||||
<App />
|
<App />
|
||||||
</HelmetProvider>
|
</HelmetProvider>
|
||||||
</LoadingProvider>
|
|
||||||
</ThemeProvider>
|
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user