update demo-react-travel-app,
This commit is contained in:
@@ -1,99 +1,102 @@
|
|||||||
import { IonCard, IonCardHeader, IonCardTitle, IonNote, useIonToast, CreateAnimation, IonIcon } from "@ionic/react";
|
import {
|
||||||
import { useState } from "react";
|
IonCard,
|
||||||
import { useRef } from "react";
|
IonCardHeader,
|
||||||
import { Iconly } from "react-iconly";
|
IonCardTitle,
|
||||||
import { heart, trashBin } from "ionicons/icons";
|
IonNote,
|
||||||
import { addFavourite } from "../store/PlacesStore";
|
useIonToast,
|
||||||
|
CreateAnimation,
|
||||||
|
IonIcon,
|
||||||
|
} from '@ionic/react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useRef } from 'react';
|
||||||
|
import { Iconly } from 'react-iconly';
|
||||||
|
import { heart, trashBin } from 'ionicons/icons';
|
||||||
|
import { addFavourite } from '../store/PlacesStore';
|
||||||
|
|
||||||
import styles from "../styles/Home.module.scss";
|
import styles from '../styles/Home.module.scss';
|
||||||
|
|
||||||
const PlaceCard = ({ place = false, fromFavourites = false }) => {
|
const PlaceCard = ({ place = false, fromFavourites = false }) => {
|
||||||
|
const animationRef = useRef(null);
|
||||||
|
const cardRef = useRef(null);
|
||||||
|
const [presentToast] = useIonToast();
|
||||||
|
const [hideAnimatedIcon, setHideAnimatedIcon] = useState(true);
|
||||||
|
|
||||||
const animationRef = useRef();
|
const floatStyle = {
|
||||||
const cardRef = useRef();
|
display: hideAnimatedIcon ? 'none' : '',
|
||||||
const [ presentToast ] = useIonToast();
|
position: 'absolute',
|
||||||
const [ hideAnimatedIcon, setHideAnimatedIcon ] = useState(true);
|
zIndex: '10',
|
||||||
|
};
|
||||||
|
|
||||||
const floatStyle = {
|
const floatGrowAnimation = {
|
||||||
|
property: 'transform',
|
||||||
|
fromValue: 'translateY(0) scale(1)',
|
||||||
|
toValue: 'translateY(-20px) scale(2)',
|
||||||
|
};
|
||||||
|
|
||||||
display: hideAnimatedIcon ? "none" : "",
|
const mainAnimation = {
|
||||||
position: "absolute",
|
duration: 600,
|
||||||
zIndex: "10"
|
iterations: '1',
|
||||||
};
|
fromTo: [floatGrowAnimation],
|
||||||
|
easing: 'cubic-bezier(0.25, 0.7, 0.25, 0.7)',
|
||||||
|
};
|
||||||
|
|
||||||
const floatGrowAnimation = {
|
const handleAddFavourite = async (e, place) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
property: "transform",
|
if (fromFavourites) {
|
||||||
fromValue: "translateY(0) scale(1)",
|
// Add a fadeOut animation before removing
|
||||||
toValue: "translateY(-20px) scale(2)"
|
cardRef.current.classList.add('animate__fadeOut');
|
||||||
};
|
|
||||||
|
|
||||||
const mainAnimation = {
|
setTimeout(() => {
|
||||||
|
addFavourite(place, fromFavourites);
|
||||||
|
}, 500);
|
||||||
|
} else {
|
||||||
|
addFavourite(place, fromFavourites);
|
||||||
|
}
|
||||||
|
|
||||||
duration: 600,
|
presentToast({
|
||||||
iterations: "1",
|
header: `Favourite ${fromFavourites ? 'removed' : 'added'}!`,
|
||||||
fromTo: [ floatGrowAnimation ],
|
buttons: [
|
||||||
easing: "cubic-bezier(0.25, 0.7, 0.25, 0.7)"
|
{
|
||||||
};
|
text: '♡',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
message: `${place.name} has been ${fromFavourites ? 'removed from' : 'added to'} your favourites.`,
|
||||||
|
duration: 1500,
|
||||||
|
color: 'success',
|
||||||
|
});
|
||||||
|
|
||||||
const handleAddFavourite = async (e, place) => {
|
setHideAnimatedIcon(false);
|
||||||
|
await animationRef.current.animation.play();
|
||||||
|
setHideAnimatedIcon(true);
|
||||||
|
};
|
||||||
|
|
||||||
e.stopPropagation();
|
return (
|
||||||
e.preventDefault();
|
<IonCard
|
||||||
|
ref={cardRef}
|
||||||
|
className={`${styles.slide} animate__animated animate__fadeIn animate__faster`}
|
||||||
|
routerLink={`/view-place/${place.id}`}
|
||||||
|
>
|
||||||
|
<div className={styles.imageHeader}>
|
||||||
|
<img src={place ? place.image : '/assets/nonefound.png'} />
|
||||||
|
{place && (
|
||||||
|
<div className="favouriteButton" onClick={(e) => handleAddFavourite(e, place)}>
|
||||||
|
<Iconly set="bold" name={fromFavourites ? 'Delete' : 'Heart'} color="red" />
|
||||||
|
|
||||||
if (fromFavourites) {
|
<CreateAnimation ref={animationRef} {...mainAnimation}>
|
||||||
|
<IonIcon icon={fromFavourites ? trashBin : heart} style={floatStyle} color="danger" />
|
||||||
|
</CreateAnimation>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
// Add a fadeOut animation before removing
|
<IonCardHeader>
|
||||||
cardRef.current.classList.add("animate__fadeOut");
|
<IonCardTitle>{place ? place.name : 'Sorry'}</IonCardTitle>
|
||||||
|
<IonNote>{place ? place.destination : 'No results found'}</IonNote>
|
||||||
setTimeout(() => {
|
</IonCardHeader>
|
||||||
addFavourite(place, fromFavourites);
|
</IonCard>
|
||||||
}, 500);
|
);
|
||||||
} else {
|
};
|
||||||
|
|
||||||
addFavourite(place, fromFavourites);
|
|
||||||
}
|
|
||||||
|
|
||||||
presentToast({
|
|
||||||
|
|
||||||
header: `Favourite ${ fromFavourites ? "removed" : "added" }!`,
|
|
||||||
buttons: [
|
|
||||||
{
|
|
||||||
text: "♡",
|
|
||||||
}
|
|
||||||
],
|
|
||||||
message: `${ place.name } has been ${ fromFavourites ? "removed from" : "added to" } your favourites.`,
|
|
||||||
duration: 1500,
|
|
||||||
color: "success"
|
|
||||||
});
|
|
||||||
|
|
||||||
setHideAnimatedIcon(false);
|
|
||||||
await animationRef.current.animation.play();
|
|
||||||
setHideAnimatedIcon(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<IonCard ref={ cardRef } className={ `${ styles.slide } animate__animated animate__fadeIn animate__faster` } routerLink={ `/view-place/${ place.id }` }>
|
|
||||||
<div className={ styles.imageHeader }>
|
|
||||||
<img src={ place ? place.image : "/assets/nonefound.png" } />
|
|
||||||
{ place &&
|
|
||||||
<div className="favouriteButton" onClick={ e => handleAddFavourite(e, place) }>
|
|
||||||
|
|
||||||
<Iconly set="bold" name={ fromFavourites ? "Delete" : "Heart" } color="red" />
|
|
||||||
|
|
||||||
<CreateAnimation ref={ animationRef } { ...mainAnimation }>
|
|
||||||
<IonIcon icon={ fromFavourites ? trashBin : heart } style={ floatStyle } color="danger" />
|
|
||||||
</CreateAnimation>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<IonCardHeader>
|
|
||||||
<IonCardTitle>{ place ? place.name : "Sorry" }</IonCardTitle>
|
|
||||||
<IonNote>{ place ? place.destination : "No results found" }</IonNote>
|
|
||||||
</IonCardHeader>
|
|
||||||
</IonCard>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default PlaceCard;
|
export default PlaceCard;
|
Reference in New Issue
Block a user