react-icons/fa#FaHeart JavaScript Examples
The following examples show how to use
react-icons/fa#FaHeart.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Footer.js From weatherman-react with GNU General Public License v3.0 | 6 votes |
Footer = () => {
return (
<div
id="footer"
className="p-4 d-flex flex-column flex-sm-column flex-md-row flex-lg-row justify-content-center align-items-center text-light w-100"
style={{ backgroundColor: "rgb(33, 37, 41)" }}
>
<div className="footer-component text-center d-flex w-100 w-md-25 my-2 my-md-0 justify-content-center">
<a href="https://github.com/dsaw/weatherman-react">Github</a>
</div>
<div className="footer-component text-center d-flex w-100 w-md-50 my-2 my-md-0 justify-content-center">
Made with
<span title="Heart" role="img" aria-label="Love">
{" "}
<FaHeart color={"#e31b23"} size={18} />{" "}
</span>
using
<span title="React" role="img" aria-label="React">
{" "}
<FaReact color={"#2acef7"} size={18} />{" "}
</span>
by <a href="/"> Devesh</a>
</div>
<div className="footer-component text-center d-flex w-100 w-md-25 my-2 my-md-0 justify-content-center">
<a href="https://github.com/dsaw/weatherman-react/blob/master/PRIVACY-POLICY.html">
Privacy Policy{" "}
</a>
</div>
</div>
);
}
Example #2
Source File: MyPostsPage.jsx From Socialgram with Apache License 2.0 | 6 votes |
Post = ({ post }) => {
return (
<div key={post.id} className="container bg-dark mt-3 mb-3 p-3 post rounded">
<h3 className="mb-3">{parse(post.title)}</h3>
<div className="icon-container d-flex">
<div className="icons" title="like">
<FaThumbsUp className="pe-1" />
<span>{post.likes}</span>
</div>
<div className="icons" title="dislike">
<FaThumbsDown className="pe-1" />
<span>{post.dislikes}</span>
</div>
<div className="icons hearts" title="heart">
<FaHeart className="pe-1" />
<span>{post.hearts}</span>
</div>
</div>
{post.comments.map((comment) => (
<div
key={comment.id}
className="container p-3 mb-2 shadow-lg rounded-lg"
>
{parse(comment.comments)}
</div>
))}
</div>
);
}
Example #3
Source File: Footer.js From ReactJS-Projects with MIT License | 5 votes |
Footer = () => {
return (
<footer className="bg-info text-center pt-3 pb-2 mt-5 sticky-bottom">
Made with <FaHeart /> using React, 2022
</footer>
);
}
Example #4
Source File: index.js From haskell.foundation with MIT License | 5 votes |
icons = { heart: <FaHeart />, lock: <FaLockOpen />, users: <FaUserFriends />, cubes: <FaCubes />, user: <FaUser /> }
Example #5
Source File: Player.jsx From bottle-radio with MIT License | 4 votes |
Player = () => {
const variables = window._env_ ? window._env_ : { REACT_ICECAST_URL: "" };
const [playing, setPlaying] = useState(false);
const [loading, setLoading] = useState(false);
const [muted, setMuted] = useState(false);
const [firstLoad, setFirstLoad] = useState(true);
const [nowPlaying, setNowPlaying] = useState(["No data", "No data"]);
const [listeners, setListeners] = useState([0, 0]);
const { colorMode } = useColorMode();
const colorHover = { light: "white", dark: "black" };
const { isOpen, onOpen, onClose } = useDisclosure();
const trackLinks = useSaveTrack(
nowPlaying[0],
nowPlaying[1]
);
const audioRef = useRef(null);
const { setPlayer } = useContext(VisualiserContext);
useEffect(() => {
const audio = document.getElementById("player");
if (audio) {
setPlayer(audioRef);
}
}, [setPlayer]);
useEffect(() => {
const updateStats = async () => {
let url = variables.REACT_ICECAST_URL + "status-json.xsl";
let response = await fetch(url);
let json = await response.json();
let track = json.icestats.source.title;
if (track && track !== "") {
let artist = track.split(" - ")[0];
track = track.split(" - ").slice(1).join(" - ");
setNowPlaying([track, artist]);
}
let listeners = json.icestats.source.listeners;
let peakListeners = json.icestats.source.listener_peak;
if (listeners && listeners) {
setListeners([listeners, peakListeners]);
}
};
updateStats();
setInterval(() => {
updateStats();
}, 10000);
}, [variables.REACT_ICECAST_URL]);
const togglePlay = () => {
let player = document.getElementById("player");
if (firstLoad) {
setFirstLoad(false);
}
if (player.paused) {
setPlaying(true);
player.load();
player.play();
} else {
setPlaying(false);
player.pause();
}
};
const changeVolume = (value) => {
let player = document.getElementById("player");
value <= 0 ? setMuted(true) : setMuted(false);
player.volume = value / 100;
};
const TrackModal = (props) => {
const { modal, setModal } = useContext(ModalContext);
useEffect(() => {
if (!modal) {
setModal(trackLinks);
}
}, [modal, setModal]);
return (
<div>
<Modal
isOpen={isOpen}
onClose={() => {
onClose();
setModal();
}}
size="sm"
isCentered
>
<ModalOverlay>
<ModalContent>
<ModalCloseButton />
<ModalBody>
<Grid templateColumns="1fr 1fr" justifyItems="center" gap={0}>
{modal && modal.length > 0 ? (
modal.map((link) => (
<Link key={link.url} href={link.url} isExternal>
<Button variant="ghost">{link.displayName}</Button>
</Link>
))
) : (
<div>
<Spinner size="sm" /> Loading...
</div>
)}
</Grid>
</ModalBody>
</ModalContent>
</ModalOverlay>
</Modal>
</div>
);
};
return (
<div>
<Flex
direction="column"
justify="center"
align="center"
width="100%"
height="100%"
>
<Box>
<Grid
m={2}
p={2}
templateColumns="auto 1fr auto"
alignItems="center"
gap={1}
>
<Box
gridRow="1/4"
w="80px"
h="80px"
aria-label="Play toggle"
as={loading ? FaSpinner : playing ? FaPauseCircle : FaPlayCircle}
onClick={togglePlay}
_hover={{ color: colorHover[colorMode] }}
mr={1}
className={loading ? "icon-spin" : ""}
/>
<Text m={0} align="center">
<strong>{nowPlaying[0]}</strong>
</Text>
<Text m={0} align="center">
{nowPlaying[1]}
</Text>
<Flex direction="row" justify="center" maxWidth={400} p={2}>
<Slider
defaultValue={100}
min={0}
max={100}
step={10}
onChange={changeVolume}
width="80px"
>
<SliderTrack>
<SliderFilledTrack bg="tomato" />
</SliderTrack>
<SliderThumb size={2} />
</Slider>
<Box
w="20px"
h="20px"
as={muted ? FaVolumeMute : FaVolumeUp}
ml={3}
/>
<audio
id="player"
crossOrigin="anonymous"
autoPlay
preload="none"
ref={audioRef}
onPlay={() => setPlaying(true)}
onPause={() => setPlaying(false)}
onLoadStart={() => {
if (!firstLoad) {
setLoading(true);
}
}}
onCanPlay={() => setLoading(false)}
>
<source
src={variables.REACT_ICECAST_URL + "radio.mp3"}
type="audio/mp3"
/>
Your browser does not support the audio element.
</audio>
</Flex>
<Text gridColumn="1/4">
<strong>Listeners: </strong>
{listeners[0]} <strong>Peak: </strong>
{listeners[1]}
</Text>
<Box gridColumn="3" gridRow="1/4" alignItems="center">
<Box
w="25px"
h="25px"
as={FaHeart}
mx={1}
onClick={onOpen}
_hover={{ color: "tomato" }}
/>
{isOpen ? <TrackModal /> : null}
</Box>
</Grid>
</Box>
</Flex>
</div>
);
}
Example #6
Source File: productItem.js From next-ecommerce with MIT License | 4 votes |
export default function ProductSection({ id, name, rating, img_url, price }) {
const cart = useQuery(CART);
const wishlist = useQuery(WISHLIST);
return (
<article>
<div className="top-buttons">
<button className="add-wishlist" onClick={() => toggleWishlist(id)}>
{wishlist.data.wishlist.products.includes(id) && (
<FaHeart size={20} color="#D8D8D8" />
)}
{!wishlist.data.wishlist.products.includes(id) && (
<FaRegHeart size={20} color="#D8D8D8" />
)}
</button>
</div>
<div className="product-img-box">
<Link href={`/product/${id}`}>
<img className="product-img" src={img_url} />
</Link>
</div>
<Link href={`/product/${id}`}>
<a className="product-name">{name}</a>
</Link>
<div className="rating">
<StarRatings
rating={parseFloat(rating)}
starRatedColor="#F9AD3D"
numberOfStars={5}
name="rating"
starDimension="20px"
starSpacing="1px"
/>
</div>
<div className="price">
<p className="price-value">${price}</p>
<button className="add-cart" onClick={() => toggleCart(id)}>
{cart.data.cart.products.includes(id) && (
<FaCartArrowDown size={18} color="#D8D8D8" />
)}
{!cart.data.cart.products.includes(id) && (
<FaCartPlus size={18} color="#D8D8D8" />
)}
</button>
</div>
<style jsx>{`
article {
display: flex;
align-items: center;
flex-direction: column;
box-sizing: border-box;
height: 100%;
padding: 24px;
background: white;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.05);
border-radius: 6px;
}
.top-buttons {
margin-bottom: 24px;
align-self: flex-end;
}
.top-buttons .add-wishlist {
background: none;
border: none;
}
.top-buttons .add-wishlist:focus {
outline: none;
}
.product-img-box {
margin-bottom: 28px;
}
.product-img {
width: 225px;
height: 160px;
object-fit: contain;
}
.product-name {
width: 80%;
line-height: 20px;
text-decoration: none;
font-weight: 500;
font-size: 14px;
text-align: center;
color: #666666;
margin-bottom: 18px;
}
.product-name:hover {
text-decoration: underline;
font-weight: 600;
}
.rating {
margin-bottom: 24px;
}
.price {
display: flex;
align-items: center;
font-weight: 900;
font-size: 16px;
color: #666666;
}
.price .add-cart {
background: none;
border: none;
margin-left: 5px;
}
.price .add-cart:focus {
outline: none;
}
`}</style>
</article>
);
}
Example #7
Source File: [id].js From next-ecommerce with MIT License | 4 votes |
export default function Home() {
const router = useRouter();
const { id } = router.query;
const cart = useQuery(CART);
const wishlist = useQuery(WISHLIST);
const { data, loading, error } = useQuery(PRODUCTS_BY_IDS, {
variables: {
id,
},
});
if ((error || !data?.productsById.length) && !loading) {
return (
<Page title="Quantum E-commerce - Products">
<ErrorAlert message="This product is not found!"></ErrorAlert>
</Page>
);
} else if (loading) {
return (
<Page title="Quantum E-commerce - Products">
<p>Loading...</p>
</Page>
);
}
return (
<Page title="Quantum E-commerce - Products">
<article>
<div className="top-buttons">
<button
className="add-wishlist"
onClick={() => toggleWishlist(data.productsById[0].id)}
>
{wishlist.data.wishlist.products.includes(
data.productsById[0].id
) && <FaHeart size={20} color="#D8D8D8" />}
{!wishlist.data.wishlist.products.includes(
data.productsById[0].id
) && <FaRegHeart size={20} color="#D8D8D8" />}
</button>
</div>
<div className="product-img-box">
<img className="product-img" src={data.productsById[0].img_url} />
</div>
<h1 className="product-name">{data.productsById[0].name}</h1>
<h3 className="product-description">
{data.productsById[0].description}
</h3>
<div className="rating">
<StarRatings
rating={parseFloat(data.productsById[0].rating)}
starRatedColor="#F9AD3D"
numberOfStars={5}
name="rating"
starDimension="20px"
starSpacing="1px"
/>
</div>
<div className="price">
<p className="price-value">${data.productsById[0].price}</p>
<button
className="add-cart"
onClick={() => toggleCart(data.productsById[0].id)}
>
{cart.data.cart.products.includes(data.productsById[0].id) && (
<FaCartArrowDown size={24} color="#D8D8D8" />
)}
{!cart.data.cart.products.includes(data.productsById[0].id) && (
<FaCartPlus size={24} color="#D8D8D8" />
)}
</button>
</div>
<style jsx>{`
article {
display: flex;
align-items: center;
flex-direction: column;
box-sizing: border-box;
height: 100%;
width: 100%;
padding: 24px;
background: white;
box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.05);
border-radius: 6px;
}
.top-buttons {
margin-bottom: 24px;
align-self: flex-end;
}
.top-buttons .add-wishlist {
background: none;
border: none;
}
.top-buttons .add-wishlist:focus {
outline: none;
}
.product-img-box {
margin-bottom: 28px;
}
.product-img {
width: 320px;
height: 230px;
object-fit: contain;
}
.product-name {
width: 80%;
line-height: 20px;
text-decoration: none;
font-weight: 500;
font-size: 22px;
text-align: center;
color: #666666;
margin-bottom: 28px;
}
.product-description {
width: 40%;
line-height: 22px;
text-decoration: none;
font-weight: 400;
font-size: 14px;
text-align: center;
color: #666666;
margin-bottom: 24px;
}
.rating {
margin-bottom: 18px;
}
.price {
display: flex;
align-items: center;
font-weight: 900;
font-size: 20px;
color: #666666;
margin-bottom: 20px;
}
.price .add-cart {
background: none;
border: none;
margin-left: 5px;
}
.price .add-cart:focus {
outline: none;
}
@media (max-width: 1000px) {
.product-img {
width: 225px;
height: 180px;
margin-bottom: 28px;
}
.product-name {
width: 80%;
line-height: 20px;
text-decoration: none;
font-weight: 500;
font-size: 18px;
text-align: center;
color: #666666;
margin-bottom: 18px;
}
.product-description {
width: 80%;
line-height: 22px;
text-decoration: none;
font-weight: 400;
font-size: 14px;
text-align: center;
color: #666666;
margin-bottom: 18px;
}
}
`}</style>
</article>
</Page>
);
}
Example #8
Source File: Footer.jsx From nextjs-prismic-blog-starter with MIT License | 4 votes |
Footer = () => {
return (
<footer
sx={{
bg: 'muted',
}}>
<div className='footer'>
{/* <div className="links-row">
<div>
<a
href="https://github.com/iamsainikhil/nextjs-prismic-blog-starter"
target="_blank"
rel="noreferrer noopener"
className="special-link"
aria-label="GitHub"
title="GitHub"
sx={{ color: 'primary' }}
onClick={() =>
trackGAEvent(
'footer links',
`clicked on GitHub link in Footer`,
'link click'
)
}
>
GitHub
</a>
</div>
<div>
<a
href="https://iamsainikhil.com/privacy-policy"
target="_blank"
rel="noreferrer noopener"
className="special-link"
aria-label="Privacy Policy"
title="Privacy Policy"
sx={{ color: 'primary' }}
onClick={() =>
trackGAEvent(
'footer links',
`clicked on Privacy Policy link in Footer`,
'link click'
)
}
>
Privacy Policy
</a>
</div>
</div> */}
<div
style={{
textAlign: 'center',
margin: '0.25rem auto',
wordSpacing: '0.2rem',
}}>
Made with{' '}
<FaHeart
style={{color: '#CC3D5C', marginBottom: '-0.25rem'}}
aria-label='Love'
title='Love'
/>{' '}
using{' '}
<SiNextDotJs
sx={{
color: 'text',
marginBottom: '-0.25rem',
}}
aria-label='NextJS'
title='NextJS'
/>{' '}
and{' '}
<picture className='prismic-icon'>
<source type='image/webp' srcSet='/prismic-icon.webp' />
<source type='image/jpeg' srcSet='/prismic-icon.jpg' />
<img
src='/prismic-icon.jpg'
alt='Prismic'
aria-label='Prismic'
title='Prismic'
className='prismic-icon'
/>
</picture>
</div>
<div className='social-row'>
{/* <Icon
name="Facebook"
url="https://facebook.com"
style={{
color: 'primary',
fontSize: '1.75rem'
}}
/> */}
<Icon
name='Twitter'
url='https://twitter.com/iamsainikhil12'
style={{
color: 'primary',
fontSize: '1.5rem',
}}
/>
<Icon
name='Medium'
url='https://medium.com/@iamsainikhil'
style={{
color: 'primary',
fontSize: '1.5rem',
}}
/>
<Icon
name='LinkedIn'
url='https://www.linkedin.com/in/iamsainikhil'
style={{
color: 'primary',
fontSize: '1.70rem',
marginBottom: '0.25rem',
}}
/>
</div>
<p style={{textAlign: 'center', marginTop: '0.5rem'}}>
© {new Date().getFullYear()}{' '}
<a
href='https://iamsainikhil.com'
target='_blank'
rel='noreferrer noopener'
className='special-link'
aria-label='Portfolio'
title='Portfolio'
sx={{color: 'primary'}}
onClick={() =>
trackGAEvent(
'footer links',
`clicked on copyright link in Footer`,
'text click'
)
}>
Sai Nikhil
</a>
</p>
</div>
</footer>
)
}
Example #9
Source File: Post.jsx From Socialgram with Apache License 2.0 | 4 votes |
Post = ({
post,
addLikes,
addComment,
disLikes,
hearts,
commentText,
setCommentText,
}) => {
const [user, setUser] = useState("");
useEffect(() => {
const ac = new AbortController();
const fetchIds = async () => {
try {
apiPlain.getSingle(`userId`, ac.signal, "").then((res) => {
if (!Array.isArray(res)) {
return;
}
const userData = res?.filter((ids) => ids._id === post.userId);
if (userData?.length) {
setUser(userData[0]?.fname);
} else {
setUser("Deleted User");
}
});
} catch (error) {
console.log(error);
}
};
fetchIds();
return () => ac.abort();
}, [post._id, post.userId, post]);
return (
<React.Fragment>
<div
key={post.id}
className="container bg-dark mt-3 mb-3 p-3 post rounded"
>
<h3 className="mb-3">{parse(post.title)}</h3>
<div className="my-4 d-flex justify-content-between">
<p className="text-muted">Posted By: {user}</p>
<p className="text-muted">
{post.date ? convertDate(post.date) : "Just now"}
</p>
</div>
<div className="icon-container d-flex">
<div
className="icons"
title="like"
onClick={() => addLikes(post.id, post.likes)}
>
<FaThumbsUp className="pe-1" />
<span>{post.likes}</span>
</div>
<div
className="icons"
title="dislike"
onClick={() => disLikes(post.id, post.dislikes)}
>
<FaThumbsDown className="pe-1" />
<span>{post.dislikes}</span>
</div>
<div
className="icons hearts"
title="heart"
onClick={() => hearts(post.id, post.hearts)}
>
<FaHeart className="pe-1" />
<span>{post.hearts}</span>
</div>
</div>
<div className="input-group mb-3 mt-3">
<form className="w-100">
<div className="form-group w-100">
<input
type="text"
className="form-control w-100"
placeholder="comment"
value={commentText}
onChange={(event) => setCommentText(event.target.value)}
required
/>
</div>
<div className="button-container text-center mt-3 mb-3">
<button
style={{ width: "100%" }}
className="btn btn-primary"
onClick={(event) => {
event.preventDefault();
addComment(post.id, post.comments);
}}
>
Add Comment
</button>
</div>
</form>
</div>
<div
style={{ maxHeight: "20vh", overflowY: "auto" }}
className="d-flex flex-column-reverse"
>
{post.comments.map((comment) => (
<div
key={comment.id}
className="container p-3 mb-2 shadow-lg rounded-lg w-100"
>
{parse(comment.comments)}
</div>
))}
</div>
</div>
</React.Fragment>
);
}
Example #10
Source File: Board.js From ytx-card-game with MIT License | 4 votes |
Board = (props) => {
const { state, dispatch } = useContext(store)
const isGamePaused = () => state.game && state.game.gamePaused
const [allyCards, setAllyCards] = useState({
[ALLY_TYPES.hand]: [],
[ALLY_TYPES.field]: [],
})
useLayoutEffect(() => {
if (state.game) {
if (state.playerNumber === 1) {
setAllyCards({
[ALLY_TYPES.hand]: [...state.game.player1.hand],
[ALLY_TYPES.field]: [...state.game.player1.field],
})
} else {
setAllyCards({
[ALLY_TYPES.hand]: [...state.game.player2.hand],
[ALLY_TYPES.field]: [...state.game.player2.field],
})
}
}
}, [state.game])
const getAllyStateType = (droppableId) => {
return allyCards[droppableId]
}
const invokeCard = (card) => {
console.log('invoke card', card)
if (!card.isInvoked) {
let me
if (state.playerNumber === 1) {
me = state.game.player1
} else {
me = state.game.player2
}
// Invokes a card into the field and updates ally hand with a new deep copy
if (me.field.length >= FIELD_SIZE) {
return dispatch({
type: 'SET_ERROR',
payload: {
error: 'The field is full',
},
})
}
if (card.cost > me.energy) {
return dispatch({
type: 'SET_ERROR',
payload: {
error:
"You don't have enough energy to invoke this card",
},
})
}
card.isInvoked = true
state.socket.emit('invoke-card', {
game: state.game,
card,
})
}
}
const onDragEnd = useCallback(
(result) => {
const { source, destination } = result
if (!destination) {
return
}
let allyState = getAllyStateType(source.droppableId)
const isEnoughEnergyToInvoke =
state.playerNumber === 1
? state.game.player1.energy
: state.game.player2.energy
console.log(
isEnoughEnergyToInvoke,
allyState.cost,
'energy',
state.playerNumber,
state.game.player1.energy,
state.game.player2.energy,
)
if (isEnoughEnergyToInvoke < allyState[source.index].cost) {
return
}
if (source.droppableId === destination.droppableId) {
const items = reorder(
allyState,
source.index,
destination.index,
)
setAllyCards({ ...allyCards, [source.droppableId]: items })
} else {
//invoke card
invokeCard(allyCards[ALLY_TYPES.hand][source.index])
const result = move(
getAllyStateType(source.droppableId),
getAllyStateType(destination.droppableId),
source,
destination,
)
setAllyCards({
[ALLY_TYPES.hand]: result[ALLY_TYPES.hand],
[ALLY_TYPES.field]: result[ALLY_TYPES.field],
})
}
},
[state.game, allyCards],
)
return (
<Page>
<ResultMsg
winner={state.gameOver && state.areYouTheWinner}
loser={state.gameOver && !state.areYouTheWinner}
>
{state.gameOver && state.areYouTheWinner
? 'Congratulations! You are the winner!'
: state.gameOver && !state.areYouTheWinner
? 'You lost! Better luck next time!'
: null}
</ResultMsg>
{/* <p>Turn: {state.game ? state.game.currentTurnNumber : 0}</p>
<p>Timer: {props.turnCountdownTimer}</p> */}
<ExitLink hidden={!state.gameOver} to="/">
Exit
</ExitLink>
{state.game ? (
<Game className="game">
<EnemyDeck>Enemy's <br /> Deck</EnemyDeck>
<YourDeck>Your <br /> Deck</YourDeck>
<EnemyStatsBox
className={
state.isAttackMode
? 'enemy-stats attack-mode'
: 'enemy-stats'
}
onClick={() => {
if (state.isAttackMode) props.attackDirectly()
}}
>
<p>Enemy</p>
<p>
{state.playerNumber === 1
? state.game.player2.life
: state.game.player1.life}
<FaHeart />
</p>
<p>
{state.playerNumber === 1
? state.game.player2.energy
: state.game.player1.energy}
<FaBolt />
</p>
</EnemyStatsBox>
<AllyStatsBox className="my-stats">
<p>You</p>
<p>
{state.playerNumber === 1
? state.game.player1.life
: state.game.player2.life}
<FaHeart />
</p>
<p>
{state.playerNumber === 1
? state.game.player1.energy
: state.game.player2.energy}
<FaBolt />
</p>
</AllyStatsBox>
<CardContainer className="cards-container enemy-cards-container">
{state.visualEnemyHand}
</CardContainer>
<Field className="field">
<DragDropContext onDragEnd={onDragEnd}>
<EnemyField
className={
state.isAttackMode
? 'enemy-field attack-mode'
: 'enemy-field'
}
>
{state.enemyFieldHtml}
</EnemyField>
<FieldContainer top >
<Droppable
droppableId={`${ALLY_TYPES.field}`}
direction="horizontal"
>
{(provided, snapshot) => (
<CardPanel
ref={provided.innerRef}
isDraggingOver={snapshot.isDraggingOver}
>
{allyCards[ALLY_TYPES.field].map(
(allyFieldCard, index) => (
<Draggable
key={index}
draggableId={`allyFieldCard${index}`}
index={index}
isDragDisabled={true}
>
{(
provided,
snapshot,
) => (
<div
ref={
provided.innerRef
}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<BoardCard
{...allyFieldCard}
/>
</div>
)}
</Draggable>
),
)}
{provided.placeholder}
</CardPanel>
)}
</Droppable>
</FieldContainer>
<FieldContainer bottom>
<Droppable
droppableId={`${ALLY_TYPES.hand}`}
direction="horizontal"
>
{(provided, snapshot) => (
<CardPanel
ref={provided.innerRef}
// isDraggingOver={snapshot.isDraggingOver}
outter
>
{allyCards[ALLY_TYPES.hand].map(
(allyHandCard, index) => (
<Draggable
key={index}
draggableId={`allyHand${index}`}
index={index}
isDragDisabled={
state.playerNumber !==
state.game
.currentPlayerTurn
}
>
{(
provided,
snapshot,
) => (
<div
ref={
provided.innerRef
}
{...provided.draggableProps}
{...provided.dragHandleProps}
>
<BoardCard
{...allyHandCard}
/>
</div>
)}
</Draggable>
),
)}
{provided.placeholder}
</CardPanel>
)}
</Droppable>
</FieldContainer>
</DragDropContext>
</Field>
<Button
className="end-turn"
disabled={state.isOtherPlayerTurn || isGamePaused()}
onClick={() => {
props.endTurn()
}}
>
End Turn
</Button>
<Button
className="surrender"
style={{
backgroundColor: 'red',
}}
disabled={isGamePaused()}
onClick={() => {
props.surrender()
}}
>
Surrender
</Button>
</Game>
) : (
<p>Game loading...</p>
)}
</Page>
)
}
Example #11
Source File: BoardCard.js From ytx-card-game with MIT License | 4 votes |
BoardCard = (props) => {
const card_names = {
one,
two,
three,
four,
five,
six,
seven,
eight,
nine,
ten,
eleven,
twelve,
tt,
zz
}
let img_name;
if (Object.keys(card_names).includes(props.card_img)) {
img_name = card_names[props.card_img]
}
const { state, dispatch } = useContext(store)
const toggleAttackMode = (cardId) => {
let isAttackMode = cardId == 0 ? false : !state.isAttackMode
dispatch({
type: 'SET_ATTACK_MODE',
payload: {
isAttackMode,
attackingCardId: cardId,
},
})
}
/**
* @dev Burns the selected card on hand and refund a part of the cost as energy to the player
* @param {String} cardID
*/
const burnCardOnHand = (cardID) => {
state.socket.emit('burn-card', {
currentGameID: state.game.gameId,
cardID,
burnType: 'hand',
})
}
const isGamePaused = () => state.game && state.game.gamePaused
let isAllyCard = state.playerNumber === props.playerNumberOwner
// If the card is ally, display the attack button or invoke, else don't display actions
let buttonToDisplay
if (props.isInvoked && isAllyCard) {
buttonToDisplay = (
<CardButton
disabled={
!props.canAttack ||
state.isOtherPlayerTurn ||
isGamePaused()
}
onClick={() => {
toggleAttackMode(props.id)
}}
>
Attack
</CardButton>
)
} else if (isAllyCard) {
buttonToDisplay = (
<div>
<CardButton
style={{
backgroundColor: '#ffad04',
}}
disabled={state.isOtherPlayerTurn || isGamePaused()}
onClick={() => {
burnCardOnHand(props.id)
}}
>
Burn
</CardButton>
</div>
)
}
const renderSwitch = (param) => {
switch (param) {
case 'wind':
return <FiWind />;
case 'fire':
return <ImFire />;
case 'water':
return <GiDrop />;
case 'death':
return <GiDeathSkull />;
case 'life':
return <FaHeart />;
case 'neutral':
return <FiMinusCircle />;
default:
return param;
}
}
return (
<StyledCard data-id={props.dataId} card_name={img_name}>
<div>{props.cost}<FaBolt size={18} /> </div>
<div><span>{props.life}</span><FaHeart color={'rgba(255, 255, 255, 0.3)'} size={26} /> </div>
<div><span>{props.attack}</span><GiBowieKnife color={'rgba(255, 255, 255, 0.3)'} size={26} /> </div>
<div className={'card ' + props.type}>{renderSwitch(props.type)}</div>
<div className="spacer"></div>
{buttonToDisplay}
</StyledCard>
)
}