Semantic-UI-React not applied using Nextjs _app.js - semantic-ui

I am using Nextjs, Semantic-UI-React, next-routes and Auth-0
In the _app.js file contains both the Head tag and the Layout component. The semantic.min.css link which is injected under the Head tag in _app.js doesn't seem to work. The css styling is not applied at all.
My workaround is to wrap all my other pages with the Layout component and the Head tag is injected inside the Layout component. However, I prefer to apply the Layout wrapper component and Head tag inside _app.js so I need not apply them in every page
Anyone knows how to resolve this? Thanks
_app.js
export default class MyApp extends App {
static async getInitialProps(c) {
const pageProps = await App.getInitialProps(c);
return { ...pageProps };
}
render() {
const { Component, pageProps } = this.props;
return (
<Layout>
<h2>Test</h2>
<Head>
<title>CyberCoin</title>
<meta
name="viewport"
content="initial-scale=1.0, width=device-width"
/>
<link
rel="stylesheet"
href="//cdn.jsdelivr.net/npm/semantic-ui#2.4.2/dist/semantic.min.css"
/>
</Head>
<Component {...pageProps} />
</Layout>
);
}
}
index.js
export default class Auth extends Component {
render() {
return (
<div>
{auth0.isAuthenticated() && (
<div>
<Link route="/main">
<a className="item">Main</a>
</Link>
</div>
)}
{!auth0.isAuthenticated() && (
<div>
<Link route="/about">
<a className="item">About</a>
</Link>
</div>
)}
{!auth0.isAuthenticated() && (
<div>
<Button onClick={auth0.login} primary>
Authorize
</Button>
</div>
)}
{auth0.isAuthenticated() && (
<div>
<Button onClick={auth0.logout} primary>
Exit
</Button>
</div>
)}
</div>
);
}
}
main.js
class CampaignIndex extends React.Component {
static async getInitialProps() {
const campaigns = await factory.methods.getDeployedCampaigns().call();
return { campaigns };
}
renderCampaigns() {
const items = this.props.campaigns.map(address => ({
header: address,
description: (
<Link route={`/campaigns/${address}`}>
<a>View Campaign</a>
</Link>
),
fluid: true
}));
return <Card.Group items={items} />;
}
render() {
return (
<div>
<div>
<h3>Open Campaigns</h3>
<Link route="/campaigns/new">
<a>
<Button
floated="right"
content="Create Campaign"
icon="add circle"
primary
/>
</a>
</Link>
{this.renderCampaigns()}
</div>
</div>
);
}
}
export default CampaignIndex;

Related

feching data dynamically using getServerSideProps in next js but error: Cannot read properties of null (reading 'useContext')

I'm trying to fetch data dynamically according to user choice, here I'm using getServerSide props inside pages/newsPages/[category].tsx
error pointing towards this:
TypeError: Cannot read properties of null (reading 'useContext')
46 export async function getServerSideProps(context: any) {
> 47 | const router = useRouter();
| ^
import { useRouter } from 'next/router'
import React, { useState } from 'react'
import Feeds from '../../components/Feeds'
import Header from '../../components/Header'
export default function category({ newsCategory }:any) {
const [date, setDate] = useState(new Date())
return (
<div className='bg-gray-100'>
<Header />
<main className='mx-5 my-5'>
<div className='bg-white'>
<div className='flex justify-between p-4'>
<h1 className='text-sm font-bold md:text-2xl'>Wellcome to clone BBC.com</h1>
<h1 className='text-sm font-bold md:text-2xl'>{date.toDateString()}</h1>
</div>
{newsCategory.articles.slice(0, 1).map((article:any )=> (
<a key={article.url} href={article.url}
className="relative">
<img className='w-full' src={article.urlToImage ? article.urlToImage: "./ALT.jpg"} alt="" />
<h1
className='text-white absolute bottom-[40%] left-[5%]
lg:text-2xl text-xl'>{article.title}</h1>
<p className='text-white absolute bottom-[30%] left-[5%] line-clamp-1'>{article.description}</p>
</a>
))}
<div className='grid grid-flow-row-dense md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4'>{/*grid start*/}
{newsCategory.articles.slice(1, newsCategory.articles.length).map((article: any) => (
<Feeds
url={article.url}
className=""
key={article.url}
urlToImage={article.urlToImage}
title={article.title}
description={article.description}
/>
))}
</div>
</div>
</main>
</div>
)
}
export async function getServerSideProps(context: any) {
const router = useRouter();
const { category } = router.query
const newsCategory = await fetch(`https://newsapi.org/v2/top-headlines?country=us&category=${category}&apiKey=${process.env.API_KEY}`)
.then(res => res.json())
return {
props: {
newsCategory,
}
}
}
pages/index.tsx
import Head from 'next/head'
import Header from '../components/Header';
import NewsFeed from '../components/NewsFeed';
export default function Home({ news }: any) {
return (
<div className='bg-gray-100 '>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<Header />
<main className='mx-5 my-5'>
<NewsFeed news={news} key={news.article}/>
</main>
</div>
)
}
export async function getServerSideProps(context: any) {
const news = await fetch("https://newsapi.org/v2/top-headlines?country=us&category=business&apiKey=")
.then(res=>res.json());
return {
props: {
news,
}
}
}
header.tsx
pushing to the newspages
<p className='hidden hover:text-blue-500 sm:inline-flex'
onClick={()=> router.push("/")}>Home</p>
<p className='hidden hover:text-blue-500 sm:inline-flex'
onClick={()=> router.push("/newsPages/general")}>News</p>
<p className='hidden hover:text-blue-500 sm:inline-flex'
onClick={()=> router.push("/newsPages/sports")}>Sport</p>
<p className='hidden hover:text-blue-500 sm:inline-flex'
onClick={()=> router.push("/newsPages/entertainment")}>Reel</p>
<p className='hidden hover:text-blue-500 sm:hidden lg:inline-flex'
onClick={()=> router.push("/newsPages/health")}>Worklife</p>
<p className='hidden hover:text-blue-500 sm:hidden lg:inline-flex'
onClick={()=> router.push("/newsPages/science")}>Science</p>
<p className='hidden hover:text-blue-500 sm:hidden lg:inline-flex'
onClick={()=> router.push("/newsPages/future")}>Future</p>
what I did wrong here, can I use getServerSideProps in multiple files inside the pages folder? why here this error occurs,

next-i18next : get the value of locale to change page dir to right to left

I just migrated to next.js and started using next-i18next instead of React i18n. my objective is to change the html page dir to right to left when choosing the Arabic language.
I was using a cookie to achieve this but I belive if I can get the value of locale in loginHeader.js component I can achieve that.
How to get the value of local ?
I highly appreciate your support.
loginHeader.js ;
import React, { Fragment, useEffect } from 'react';
import styles from '../styles/LoginHeader.module.css';
import Link from 'next/link';
import { connect } from 'react-redux';
import { logout } from '../actions/auth';
import SortIcon from '#mui/icons-material/Sort';
import ExpandMoreIcon from '#mui/icons-material/ExpandMore';
import Alert from './Alert';
// import Drower from './Drower';
import Logo from '../assets/images/logoo.png';
import { useTranslation } from 'next-i18next';
import { Select, MenuItem } from '#mui/material';
import LanguageIcon from '#mui/icons-material/Language';
import { Link as Scroll } from 'react-scroll';
import Image from 'next/image';
import {useRouter} from 'next/router';
import i18n from '../../i18n';
import cookies from 'js-cookie';
const languages = [
{
code: 'fr',
name: 'Français',
country_code: 'fr'
},
{
code: 'en',
name : 'English',
country_code: 'en'
},
{
code: 'ar',
name: 'العربية',
country_code: 'ly',
dir: 'rtl'
}
]
//this is new code but the value isn't there
export function getServerSideProps({locale}) {
return {
props: {
locale
}
}
};
function LoginHeader(props, { logout, isAuthenticated }) {
// This is old code before migration
const currentLanguageCode = cookies.get('i18next') || 'en';
const currentLanguage = languages.find(l => l.code === currentLanguageCode);
useEffect (() => {
document.body.dir = currentLanguage.dir || 'ltr'
// document.title = t('app_title')
},[currentLanguage]);
const { t } = useTranslation();
const router = useRouter();
const guestLinks = () => (
<Fragment>
<div className={styles.loginHeader__right}>
<div className='middle__header__bx'>
<div className={styles.loginHeader__main__btns}>
<Link className={styles.loginHeader__loginButton} href='/login'><button className={styles.login__btn}>{t('header_login')}</button></Link>
<Link className={styles.loginHeader__signupButton} href='/signup'><button className={styles.signup__btn}>{t('header_signup')}</button></Link>
</div>
<div className={styles.loginHeader__services__dropdown}>
<Scroll offset={-100} to='services'><button className={styles['dropdown__btn']+' '+styles['dropdown__services']}>{t('header_services')}<ExpandMoreIcon className={styles.services__expand}/></button></Scroll>
<div className={styles['dropdown__content']+' '+styles['dropdown__services__content']}>
<Link className={styles.loginHeader__menuItem} href='/admission'>{t('services_addmissionOffers')}</Link>
{/* <Link className='loginHeader__menuItem' to='/application-form'>{t('services_forms')}</Link> */}
<Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('services_premium')}</Link>
<Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('services_visaAssist')}</Link>
</div>
</div>
{/* start of lang box */}
<Select
className={styles.loginHeader__select}
labelId='select-demo'
id='language-select'
disableUnderline
variant='standard'
IconComponent={LanguageIcon}
>
{router.locales.map((locale) => (
<MenuItem
className={styles.loginHeader__select__menu}
key={locale}
>
<Link href={router.asPath} locale={locale}>
<a>{locale}</a>
</Link>
</MenuItem>
))}
</Select>
{/* end of lang box */}
<div className={styles['loginHeader__services__dropdown']+' '+styles['sortIcon__bx']}>
<SortIcon className={styles['dropdown__btn']+' '+styles['loginHeader__sortIcon']}/>
<div className={styles['dropdown__content']+' '+styles['sortIcon__dropdown']}>
<Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('header_dropdown_prem')}</Link>
<Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
<Link className={styles.loginHeader__menuItem} href='/admission'>{t('header_dropdown_admission')}</Link>
<Link className={styles.loginHeader__menuItem} href='/request-service'>{t('header_dropdown_requestService')}</Link>
<Link className={styles.loginHeader__menuItem} href='/contact'>{t('header_dropdown_contact')}</Link>
<Link className={styles.loginHeader__menuItem} href='/signup'>{t('header_signup')}</Link>
<Link className={styles.loginHeader__menuItem} href='/login'>{t('header_login')}</Link>
<Link className={styles.loginHeader__menuItem} href='/guid'>{t('header_dropdown_guide')}</Link>
</div>
</div>
</div>
</div>
</Fragment>
);
const authLinks = () => (
<Fragment>
<div className={styles.loginHeader__right}>
<div className={styles.middle__header__bx}>
<div className={styles.loginHeader__main__btns}>
<Link className={styles.loginHeader__loginButton} href='/login'><button className={styles.login__btn}>{t('header_login')}</button></Link>
<Link className={styles.loginHeader__signupButton} href='/signup'><button className={styles.singin__btn}>{t('header_signup')}</button></Link>
</div>
<div className={styles.loginHeader__services__dropdown}>
<Scroll offset={-100} to='services'><button className={styles['dropdown__btn']+' '+styles['dropdown__services']}>{t('header_services')}<ExpandMoreIcon className={styles.services__expand}/></button></Scroll>
<div className={styles['dropdown__content']+' '+styles['dropdown__services__content']}>
<Link className={styles.loginHeader__menuItem} href='/admission'>{t('services_addmissionOffers')}</Link>
{/* <Link className='loginHeader__menuItem' to='/application-form'>{t('services_forms')}</Link> */}
<Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('services_premium')}</Link>
<Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('services_visaAssist')}</Link>
</div>
</div>
{/* start of lang box */}
<Select
className={styles.loginHeader__select}
labelId='select-demo'
id='language-select'
disableUnderline
variant='standard'
IconComponent={LanguageIcon}
>
{languages.map(({code, name, country_code}) =>
<MenuItem
key={country_code}
>
<button
onClick={() => i18next.changeLanguage(code)}
className='loginHeader__lang__btn'
>
{name}
</button>
</MenuItem>
)}
</Select>
{/* end of lang box */}
<div className={styles['loginHeader__services__dropdown']+' '+styles['loggedin__icon__bx']}>
<button className={styles.dropdown__btn}><SortIcon className={styles['loginHeader__sortIcon']+' '+styles['logedin__sortIcon']}/></button>
<div className={styles['dropdown__content']+' '+styles['logged__sortIcon__dropdown']}>
<Link className={styles.loginHeader__menuItem} href='/premuim-support'>{t('header_dropdown_prem')}</Link>
<Link className={styles.loginHeader__menuItem} href='/admission'>{t('header_dropdown_admission')}</Link>
<Link className={styles.loginHeader__menuItem} href='/visa-assist'>{t('header_dropdown_visaAssist')}</Link>
<Link className={styles.loginHeader__menuItem} href='/request-service'>{t('header_dropdown_requestService')}</Link>
<Link className={styles.loginHeader__menuItem} href='/contact'>{t('header_dropdown_contact')}</Link>
<Link className={styles.loginHeader__menuItem} href='/guid'>{t('header_dropdown_guide')}</Link>
<button onClick={logout} className={styles.logout__btn}>{t('header_logout')}</button>
</div>
</div>
</div>
</div>
</Fragment>
);
return (
<div className={styles.loginHeader}>
<div className={styles.loginHeader__left}>
<Link href='/'><Image className={styles.logo} src={Logo} alt='logo'/></Link>
</div>
{isAuthenticated ? authLinks() : guestLinks()}
<Alert/>
</div>
)
};
const mapStateToProps = state => ({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps, { logout }) (LoginHeader);
i18n.js :
const path = require('path');
module.exports = {
i18n: {
locales: ['ar', 'en', 'fr'],
defaultLocale: 'en',
localeDetection: false,
localePath: path.resolve('./public/locales'),
},
};
next.config.js ;
const { i18n } = require('./i18n');
const nextConfig = {
reactStrictMode: true,
i18n,
};
module.exports = nextConfig;
Thanks to Juliomalves who guided me to the solution. So, I changed two parts in my code :
1st :
const router = useRouter();
const [show, setShow] = useState (false);
const currentLanguageCode = router.locale;
const currentLanguage = languages.find(l => l.code === currentLanguageCode);
useEffect (() => {
document.body.dir = currentLanguage.dir || 'ltr'
// document.title = t('app_title')
},[currentLanguage]);
2nd :
<div className={styles.lang__container}>
{languages.map(({code, name, country_code}) =>
<MenuItem
className={styles.loginHeader__select__menu}
key={country_code}
>
<Link className={styles.loginHeader__lang__btn} href={router.asPath} locale={code}>
<a>{name}</a>
</Link>
</MenuItem>
)}
</div>

How to change overflow style to hidden when modal opens

I am trying to create react app and i want overflow to hidden when button is pressed,
i want to display contact form on modal but overflow is running everything i can scroll even with modal is open
Here is my navbar with button
import React from "react";
import { useState, useEffect } from "react";
import { Link } from "react-router-dom";
import { FaBars, FaTimes } from "react-icons/fa";
import "./Navbar.css";
import { IconContext } from "react-icons/lib";
import Button from "./Button";
import Modal from "./Contact Form/Modal";
import { motion, AnimatePresence } from "framer-motion";
export default function Navbar() {
const [click, setClick] = useState(false);
const [button, setButton] = useState(true);
const [modalOpen, setModalOpen] = useState(false);
function closeModal() {
setModalOpen(false);
}
function openModal() {
setModalOpen(true);
}
function handleClick() {
setClick(!click);
}
function closeMobileMenu() {
setClick(false);
}
function showButton() {
if (window.innerWidth <= 960) {
setButton(false);
} else {
setButton(true);
}
}
function closeMobileMenu() {
setClick(false);
}
useEffect(() => {
showButton();
}, []);
window.addEventListener("resize", showButton);
return (
<>
<IconContext.Provider value={{ color: "#fff" }}>
<div className="navbar">
<div className="navbar-container container">
<Link to="/" className="navbar-logo" onClick={closeMobileMenu}>
LOGO
</Link>
<div className="menu-icon" onClick={handleClick}>
{click ? <FaTimes /> : <FaBars />}
</div>
<ul className={click ? "nav-menu active" : "nav-menu"}>
<li className="nav-item">
<Link to="/" className="nav-links" onClick={closeMobileMenu}>
Home
</Link>
</li>
<li className="nav-item">
<Link to="/" className="nav-links" onClick={closeMobileMenu}>
About Us
</Link>
</li>
<li className="nav-item">
<Link to="/" className="nav-links" onClick={closeMobileMenu}>
Contact Us
</Link>
</li>
{/* Main button */}
<li className="nav-btn">
{button ? (
<Link to='' className="btn-link">
<motion.button
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className="btn--outline"
onClick={() => (modalOpen ? closeModal() : openModal())} //modal opens
>
CONTACT US
</motion.button>
</Link>
) : (
<Link
to=""
className="btn-link"
onClick={closeMobileMenu}
>
<motion.button
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
className="btn--mobile"
buttonSize='btn--mobile'
buttonStyle='btn--outline'
onClick={() => {(modalOpen ? closeModal() : openModal())}} //modal opens
>
Contact US
</motion.button>
</Link>
)}
</li>
</ul>
</div>
</div>
<AnimatePresence
// Disable any initial animations on children that
// are present when the component is first rendered
initial={false}
// Only render one component at a time.
// The exiting component will finish its exit
// animation before entering component is rendered
exitBeforeEnter={true}
// Fires when all exiting nodes have completed animating out
onExitComplete={() => null}
>
{modalOpen && <Modal modalOpen={modalOpen} handleClose={closeModal} />}
</AnimatePresence>
</IconContext.Provider>
</>
);
}
I was trying to do it use State but it didn't work. I use style effect but i didn't manage to achieve it
You will make a boolean state with an initial value set to false.
When the button is clicked you will update the state from false to true and I will recommend it for you instead of making it true. then you will use this state easily with your style property and do what you need.
change the style bellow based on your needs.
import { useState } from "react";
export default function App() {
const [clicked, setClicked] = useState(false);
return (
<div className="App">
<h1 style={{ display: clicked ? "none" : "block" }}>Hello
CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2>
<button onClick={() => setClicked(!clicked)}>click</button> <= here instead of making it true. I made it the oppesite of the previous value. to toggle between them.
</div>
);
}

Pass CSS variable as prop to the react component

I am having this component that can be displayed in different colors depending on prop color that component received.
const Card = ({color}) => {
return (
<p style={{color}}>Some Text</p>
)
}
I am having these global css variables:
:root{
--bg-clr-1: #E7F8F8;
--card-clr-red: #F03E3E;
--card-clr-violet: #7950F2;
--card-clr-green: #12B886;
--text-clr: #333;
}
Is there a way to pass this css variable as prop to "Card" component? Like so:
import variableStyles from '../../styles/globalVariables.css'
const App = () => {
return(
<Card color={variableStyles['--text-clr']} />
)
}
You can pass the variable string as a props, and inject that into var():
<p style={{ color: `var(${color})` }}>Some Text</p>
const Card = ({color}) => {
return (
<p style={{ color: `var(${color})` }}>Some Text</p>
)
}
class Example extends React.Component {
render() {
return (
<React.Fragment>
<Card color={'--card-clr-red'} />
<Card color={'--card-clr-violet'} />
</React.Fragment>
);
}
}
ReactDOM.render(<Example />, document.body);
:root{
--bg-clr-1: #E7F8F8;
--card-clr-red: #F03E3E;
--card-clr-violet: #7950F2;
--card-clr-green: #12B886;
--text-clr: #333;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

React in CSS with react in viewport

I am using react in viewport from here: https://github.com/roderickhsiao/react-in-viewport and I set up the boiler plate so that the following line of code works:
<ViewportBlock onEnterViewport={() => console.log('enter')} onLeaveViewport={() => console.log('leave')} />
Looking at console.log it is saying enter and leave where I need it too. However, I need to have it say onEnterViewport set .Header (the css className is Header) to display:none in css, and onLeaveViewport set to display:block
Edit:
Full code:
const Block = (props: { inViewport: boolean }) => {
const { inViewport, forwardedRef } = props;
const color = inViewport ? '#217ac0' : '#ff9800';
const text = inViewport ? 'In viewport' : 'Not in viewport';
return (
<div className="viewport-block" ref={forwardedRef}>
{/* <h3>{ text }</h3>
<div style={{ width: '400px', height: '300px', background: color }} /> */}
<Link to="Header" spy={true} smooth={true} offset={-100} duration={1400}><img src={arrow} alt="arrow" className={inViewport ? 'hide' : 'Header-div2-mainnav-arrow' } /></Link>
</div>
);
};
const ViewportBlock = handleViewport(Block, /** options: {}, config: {} **/);
export const Header = () => ({
componentDidMount: function() {
Events.scrollEvent.register('begin', function(to, element) {
console.log('begin', arguments);
});
Events.scrollEvent.register('end', function(to, element) {
console.log('end', arguments);
});
scrollSpy.update();
},
componentWillUnmount: function() {
Events.scrollEvent.remove('begin');
Events.scrollEvent.remove('end');
},
scrollToBottom: function() {
scroll.scrollToBottom();
},
handleSetActive: function(to) {
console.log(to);
},
render: function() {
return (
<div className="Header">
<div className="Header-div1">
{/* background image */}
<h1 className="Header-div1-number">910-910-910</h1>
<h2 className="Header-div1-email">larryslawn#gmail.com</h2>
</div>
<div className="Header-div2">
<h1 className="Header-div2-h1"><span className="Header-div2-span">Larry's </span>Lawn Mowing</h1>
<p className="Header-div2-p">No job too big or too small, we do it all </p>
<div className="Header-div2-mainnav">
<Link to="Pricing" spy={true} smooth={true} offset={-50} duration={1200}><p>Pricing</p></Link>
<Link to="Services" spy={true} smooth={true} offset={-100} duration={1200}><p className="Header-div2-mainnav-p">Services</p></Link>
<Link to="Contact" spy={true} smooth={true} offset={-100} duration={1400}><p>Contact</p></Link>
</div>
<Block />
</div>
</div>
)
}
})
Use useState to toggle a class with display: none on the Header component:
const Example = () => {
const [inView, setInView] = useState(false)
return (
<>
<ViewportBlock
onEnterViewport={() => setInView(true)}
onLeaveViewport={() => setInView(false)}
/>
<Header className={inView ? 'hide' : '' }>Header</Header>
</>
)
}
CSS:
hide { display: none; }

Resources