currently working on a simple navbar component. The following is my code:
{isLoggedIn ?
<Navbar.Brand ><Link to="/" style={{ textDecoration: 'none' }} onClick={() => dispatch(logoutUser())}>Logout</Link></Navbar.Brand>
:
<Navbar.Brand ><Link to="/registration" style={{ textDecoration: 'none' }}>Register</Link></Navbar.Brand>
<Navbar.Brand ><Link to="/login" style={{ textDecoration: 'none' }}>Login</Link></Navbar.Brand>
}
When the user is logged in, I want a logout button to appear, and when they are not logged in I want both register and login buttons to appear. But I cannot do both at the same time when isLoggedIn is false. Any way to do this?
Thank you!
{isLoggedIn ? <Navbar.Brand ><Link to="/" style={{ textDecoration: 'none' }} onClick={() => dispatch(logoutUser())}>Logout</Link></Navbar.Brand>
: <div>
<Navbar.Brand ><Link to="/registration" style={{ textDecoration: 'none' }}>Register</Link></Navbar.Brand>
<Navbar.Brand ><Link to="/login" style={{ textDecoration: 'none' }}>Login</Link></Navbar.Brand>
</div>
}
Edit: as suggested below, it is also possible to wrap between fragments.
Related
I'm using antd card component to display the card and loading is not working, I gave the loading based on the api response, i got the correct response but the loading is not working for me.... if i set the loading value to true it is working fine but it is not working while i'm passing the data.
useEffect(() => {
let keys = [{ key: "get_search_records", loading: true }];
dispatch(
dynamicRequest(keys, get_search_records_query, {
searchString: state,
})
);
}, [state]);
I'm getting data and changing the loading here and it is working fine, the loading also changes perfectly but it is not reflecting in the card component
<Box>
<HStack marginLeft={10} space={20} flexWrap={'wrap'}>
{items?.map((item, index) => (
<VStack marginTop={"30px"} space={10} flexWrap={"wrap"}>
<Card
loading={loading}
hoverable
style={{ height: 430 ,width: 250, borderRadius: "10px", marginTop:30, marginBottom: 30 }}
cover={
<HStack>
<Box width={"50%"}>
<div class="card_div">
<div style={{marginTop:"5px"}}>
<Text color={"white"} alignItems="center" marginLeft={"17px"} marginTop={"7px"} >
Hot
</Text>
</div>
</div>
</Box>
<Box flexDirection="row-reverse" marginTop={"-30px"} marginRight={"10px"} padding={"5px"}>
<Typography.Link onClick={handleAddCart}>
<Tooltip className="tooltip-wishlist" color=" #3BB77E" title="Add to wishlist" placement="bottom">
<AiOutlineHeart size={"25px"}/>
</Tooltip>
</Typography.Link>
</Box>
</HStack>
}
>
<Box alignContent={"center"} height="170px">
{/* <AspectRatio w="100%" ratio={16/9}> */}
<Image
alt="Image"
src={item?.vendor_product?.product?.gallery?.[0]}
// width="90%"
preview={false}
/>
</Box>
<Box alignContent={"center"}>
<Text bold> </Text>
<VStack space={1.5}>
<Box height="130px">
<Text color={"#adadad"}>
{item.vendor_product.product.category.name}
</Text>
<Text onPress={handleClick} onMouseOver={mouseOver} onMouseOut={MouseOut} bold>{item.name} </Text>
<Rating count={item?.product_rating?.[0]?.rating}/>
<Text onPress={handleTextPress}>
By <span style={{ color: "#22c55e" }} onMouseOver={mouseOverVendor} onMouseOut={mouseOutVendor} >Theni FBO</span>
</Text>
</Box>
<HStack justifyContent="space-between">
{item.discount && (
<Text color="green.500">₹ {item.base_price}</Text>
)}
<Text strikeThrough color="green.500">
₹ {item.selling_price}
</Text>
<Button onClick={addCart} className="cart-btn" icon={<BsCart3 />}>
Add
</Button>
</HStack>
</VStack>
</Box>
</Card>
</VStack>
))}
</HStack>)}
</Box>
this is my antd card code... anyone please tell me why the loading is not working properly.
i am trying to create a sidebar with drop down
like this example in react js
https://www.w3schools.com/howto/howto_js_dropdown_sidenav.asp
i was able to design it using react the issue is that when i click on a inner li
the dropdown closes i dont want it to close
this.state = { isOpen: false, }
Clickhandler() {
this.setState({ isOpen: !this.state.isOpen });
}
<li style={styles.listItem}
onClick={this.Clickhandler}
className={this.state.isOpen ? "admintabs" : ""}
>
<div>
<FontAwesomeIcon
icon={faHistory}
style={{ marginRight: "1rem" }}
/>
</div>
<div> Internal users</div>
<div>
{" "}
<FontAwesomeIcon icon={faCaretDown} />
</div>
</li>
{this.state.isOpen ? (
<>
<NavLink
to="/admin/saler"
activeClassName="active3"
onClick={this.Clickhandler}
>
<li style={styles.listItem}>
<div>
<FontAwesomeIcon
icon={faCube}
style={{ marginRight: "1rem" }}
/>
</div>
<div> saler</div>
</li>
</NavLink>
<NavLink
to="/admin/con"
activeClassName="active3"
onClick={this.Clickhandler}
>
<li style={styles.listItem}>
<div>
<FontAwesomeIcon
icon={faBriefcaseMedical}
style={{ marginRight: "1rem" }}
/>
</div>
<div> Con</div>
</li>
</NavLink>
</>
) : null}
my code is too big so i added in codesand box
https://codesandbox.io/s/stupefied-hooks-9qm66s?file=/src/App.js
Here is my *Navbar
import React, { useState } from "react";
import { Layout, Menu } from "antd";
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
UserOutlined,
VideoCameraOutlined,
UploadOutlined,
} from "#ant-design/icons";
import { Link } from "react-router-dom";
const { Header, Sider, Content } = Layout;
const Navbar = (props) => {
const [collapsed, setCllapsed] = useState(false);
const toggle = () => {
setCllapsed(!collapsed);
};
return (
<div>
<Layout id="components-layout-demo-custom-trigger">
<Sider trigger={null} collapsible collapsed={collapsed}>
<div className="logo" />
<Menu theme="dark" mode="inline" defaultSelectedKeys={["1"]}>
<Menu.Item key="1" icon={<UserOutlined />}>
<Link style={{ textDecoration: "none" }} to="/">
Dashboard
</Link>
</Menu.Item>
<Menu.Item key="2" icon={<UserOutlined />}>
<Link style={{ textDecoration: "none" }} to="/groups">
Groups
</Link>
</Menu.Item>
<Menu.Item key="3" icon={<VideoCameraOutlined />}>
<Link style={{ textDecoration: "none" }} to="/tutors">
Tutors
</Link>
</Menu.Item>
<Menu.Item key="4" icon={<UserOutlined />}>
<Link style={{ textDecoration: "none" }} to="/students">
Students
</Link>
</Menu.Item>
</Menu>
</Sider>
<Layout className="site-layout">
<Header className="site-layout-background" style={{ padding: 0 }}>
{React.createElement(
collapsed ? MenuUnfoldOutlined : MenuFoldOutlined,
{
className: "trigger",
onClick: toggle,
}
)}
</Header>
<Content
className="site-layout-background"
style={{
margin: "24px 16px",
padding: 24,
minHeight: 280,
}}
>
{props.children}
</Content>
</Layout>
</Layout>
</div>
);
};
export default Navbar;
In this example I was using <Menu.Item></Menu.Item> component from antd . But it stopped working when clicked once. It changed onclick function. After adding from react-router-dom, I am having trouble with SelectedKeys of Antdesign's Layout. Before Link component of react-router-dom selectedKeys was working when you click one time, but after adding Link component, SelectedKeys is working when double clicked. How can I solve it? I need this should work once. Anyone can help me?
Now i have used state hook to hide the Form when the page loads. And upon the click or toggle of the radio I'm able to show the Form, But if i toggle the radio again, the form is not hiding.
This is what i have implemented:
const WelcomeTab = () => {
const [toggle, settoggle] = useState(false);
return (
<React.Fragment>
<Tab.Pane
style={{
borderRadius: '7px',
padding: '30px',
}}
attached={false}
>
<Grid>
<Grid.Row>
<Grid.Column floated="left" width={8}>
<Header
style={{
fontSize: '18px',
fontFamily: 'Nunito-Regular',
color: '#4F4F4F',
}}
>
Welcome Screen
</Header>
</Grid.Column>
<Grid.Column floated="right" width={4}>
<Header
as="h4"
style={{
display: 'flex',
justifyContent: 'space-around',
marginLeft: '30px',
}}
>
Customize
<Radio toggle onChange={() => settoggle({ toggle: !toggle })} />
</Header>
</Grid.Column>
</Grid.Row>
</Grid>
{toggle ? (
<Form style={{ paddingTop: '20px' }}>
<Form.Field>
<label style={lableStyle}>Title</label>
<input style={{ marginBottom: '20px' }} />
<label style={lableStyle}>Message</label>
<TextArea />
</Form.Field>
</Form>
) : null}
</Tab.Pane>
</React.Fragment>
);
};
const lableStyle = {
fontFamily: 'Nunito-Regular',
fontWeight: 400,
color: '#4F4F4F',
fontSize: '15px',
display: 'inline-block',
marginBottom: '10px',
};
export default WelcomeTab;
try to add useEffect hook along with change like below,
you no longer need to {} this is old syntax of setState, using hooks we directly make the changes, hope this helps
useEffect(()=>{},[toggle])
replace this wrong syntax code, i can see its not json its boolean value
<Radio toggle onChange={()=>settoggle({toggle: !toggle})}/>
as this is old syntax not work with hooks, try to implment this instead,
<Radio toggle onChange={()=>settoggle(!toggle)}/>
I have a react component that upon clicking showMore. it will load more comments. The issue im facing is that
View {showMore} More Comments
is not showing the items that are left in the array. Currently there are 7 comments in an array, and if you click show more, it will initially read show 3 more, but when i click again it says show 6 more. when it should be a lesser number than 6. It should be like show 2 more, etc. I'm quite confused on how to go about writing this logic.
What am i doing wrong
CommentList.tsx
import React, { Fragment, useState } from "react";
import Grid from "#material-ui/core/Grid";
import List from "#material-ui/core/List";
import Typography from "#material-ui/core/Typography";
import CommentItem from "./../commentItem/CommentItem";
import moment from "moment";
import OurLink from "../../../common/OurLink";
import OurSecondaryButton from "../../../common/OurSecondaryButton";
import OurModal from "../../../common/OurModal";
.....
function CommentList(props: any) {
const [showMore, setShowMore] = useState<Number>(3);
const [openModal, setOpenModal] = useState(false);
const [showLessFlag, setShowLessFlag] = useState<Boolean>(false);
const the_comments = props.comments.length;
const inc = showMore as any;
const showComments = (e) => {
e.preventDefault();
if (inc + 3 <= the_comments) {
setShowMore(inc + 3);
} else {
setShowMore(the_comments);
}
// setShowLessFlag(true);
};
........
const showMoreComments = () => {
return props.comments
.slice(0, showMore)
.sort((a, b) => a.id - b.id)
.map((comment, i) => (
<div key={i}>
<List style={{ paddingBottom: "20px" }}>
<img alt="gravatar" style={{ margin: "-10px 15px" }} src={comment.author.gravatar} width="30" height="30" />
<Typography style={{ display: "inline-block", fontWeight: 700, padding: "5px 0px" }} variant="h6" align="left">
{Object.entries(props.currentUser).length === 0 ? (
<Fragment>
<span style={{ cursor: "pointer", fontSize: "12px", fontWeight: isBold(comment) }} onClick={handleClickOpen}>
{comment.author.username}
</span>
{comment.userId === props.userId && <span style={{ fontSize: "12px" }}> (OP)</span>}
{openModal ? <OurModal open={openModal} handleClose={handleCloseModal} /> : null}
</Fragment>
) : (
<Fragment>
<OurLink
style={{ fontSize: "12px", fontWeight: isBold(comment) }}
to={{
pathname: `/profile/${comment.author.username}`,
}}
title={comment.author.username}
/>
{comment.userId === props.userId && <span style={{ fontSize: "12px" }}> (OP)</span>}
</Fragment>
)}
</Typography>
<div style={ourStyle}>
<CommentItem comment={comment} user={props.user} postId={props.postId} {...props} />
<Typography style={{ fontSize: "12px" }} variant="body1" align="left">
{moment(comment.createdAt).calendar()}
</Typography>
</div>
</List>
</div>
));
};
console.log(props.comments.slice(0, showMore).length);
return (
<Grid>
<Fragment>
<div style={{ margin: "30px 0px" }}>
<OurSecondaryButton onClick={(e) => showComments(e)} component="span" color="secondary">
View {showMore} More Comments
</OurSecondaryButton>
</div>
</Fragment>
{showLessFlag === true ? (
// will show most recent comments below
showMoreComments()
) : (
<Fragment>
{/* filter based on first comment */}
{props.comments
.filter((item, i) => item)
.sort((a, b) => b.id - a.id)
.slice(0, showMore)
.map((comment, i) => (
<div key={i}>
<List style={{ paddingBottom: "20px" }}>
<img alt="gravatar" style={{ margin: "-10px 15px" }} src={comment.author.gravatar} width="30" height="30" />
<Typography style={{ display: "inline-block", fontWeight: 700, padding: "5px 0px" }} variant="h6" align="left">
{Object.entries(props.currentUser).length === 0 ? (
<Fragment>
<span style={{ fontSize: "12px", cursor: "pointer", fontWeight: isBold(comment) }} onClick={handleClickOpen}>
{comment.author.username}
{comment.userId === props.userId && <span style={{ fontSize: "12px" }}> (OP)</span>}
</span>
{openModal ? <OurModal open={openModal} handleClose={handleCloseModal} /> : null}
</Fragment>
) : (
<Fragment>
<OurLink
style={{ fontSize: "12px", fontWeight: isBold(comment) }}
to={{
pathname: `/profile/${comment.author.username}`,
}}
title={comment.author.username}
/>
{comment.userId === props.userId && <span style={{ fontSize: "12px" }}> (OP)</span>}
</Fragment>
)}
</Typography>
<div style={ourStyle}>
<CommentItem comment={comment} user={props.user} postId={props.postId} {...props} />
<Typography style={{ fontSize: "12px" }} variant="body1" align="left">
{moment(comment.createdAt).calendar()}
</Typography>
</div>
</List>
</div>
))}
</Fragment>
)}
</Grid>
);
}
// prevents un-necesary re renders
export default React.memo(CommentList);
You want to show 3 more comments each time, or 1-2 items if there are less than 3 items left. So "View 3 More comments" if there are more than 3 left, or "View 1/2 More Comments" if there are only 1 or 2 left.
Or in other words cap the number of new comments shown at 3:
the minimum value of either 3 or (total number of comments - current shown comments = number of comments left).
View {Math.min(3, the_comments - inc)} More Comments