How to format description text coming from a CMS - javascript

Im getting text data coming from a CMS. In the CMS, I have entered text with spaces and bullet points and expect them to appear just as I have entered them. But when I grab it to use in the front end, it comes out all together, unformatted. Is there any way I can create spaces, and add bullet points to the front end based on what the description has?
Here is what I have in the cms:
But it comes out all together and unformatted in the front end. Is there any way I can make it appear like below?
Here is my code:
export default function LargeImageText({
title,
subtitle,
description,
html,
image,
cta,
className = "",
}) {
const { accessible } = useAppState();
const cl = accessible ? () => null : _classes(styles);
return (
<section className={cl(["root", className])}>
<Container>
<div className={cl("inner")}>
<div className={cl("image")}>
<Image src={image?.src} alt={image?.alt} />
</div>
<div className={cl("details")}>
<Text text={subtitle} component="h3" font="secondary" />
<Text
text={title}
variant="h3"
component="h1"
className={cl("title")}
/>
{description && (
<Text
text={description}
component="p"
className={cl("description")}
/>
)}
{html && <Wysiwyg html={html} className={cl("description")} />}
{cta && (
<CTA
link={cta?.link}
text={cta?.text}
variant="outline_transparent"
className={cl("cta")}
/>
)}
</div>
</div>
</Container>
</section>
);
}
Any help is appreciated. Thanks!

Related

How to make the cropped image to be square instead of circular in react-avatar-edit

I am using react-avatar-edit to allow a user crop their images before saving to database. It only shows a circular crop thereby making the uploaded images circular but I want to have a rectanglar crop. I can't seem to find a prop for that in the documentation. Please has anyone achieved that yet?
import Avatar from "react-avatar-edit";
function App() {
const [preview, setPreview] = useState(null);
function onClose() {
setPreview(null);
}
function onCrop(pv) {
setPreview(pv);
}
function onBeforeFileLoad(elem) {
if (elem.target.files[0].size > 71680) {
alert("File is too big!");
elem.target.value = "";
}
}
return (
<div>
<Avatar
width={300}
height={300}
onCrop={onCrop}
onClose={onClose}
onBeforeFileLoad={onBeforeFileLoad}
src={null}
/>
{preview && <img src={preview} alt="Preview" />}
</div>
);
}
export default App;
Screenshot showing the circular preview. I want square one
I also searched the documentation but was not able to find anything that allowed square crop but you can save as square by passing
exportAsSquare, sandbox link : https://codesandbox.io/s/winter-glitter-pfgysk?file=/src/App.js
<Avatar
exportAsSquare
width={300}
height={300}
onCrop={onCrop}
onClose={onClose}
onBeforeFileLoad={onBeforeFileLoad}
src={null}
/>
Adding exportSize={500} eventually solved it for me like so:
<Avatar
exportAsSquare
exportSize={500}
width={300}
height={300}
onCrop={onCrop}
onClose={onClose}
onBeforeFileLoad={onBeforeFileLoad}
src={null}
/>

text string must be rendered within a text component

I'm getting this error I read some ways to fix it , but nothing worked
<View style={styles.container}>
<StatusBar
backgroundColor="transparent"
translucent
barStyle={theme.dark ? 'light-content' : 'light-content'}
/>
{open ? (
<DateTimePicker
style={{width: '100%', margin: 5}}
mode="date"
value={date}
dateFormat="day month year"
display="calendar"
onChange={handleDate}
/>
) : (
<Button
style={{margin: 5}}
color="#17E5C2"
onPress={() => {
setOpen(true);
}}>
Filtrar por data
</Button>
)}
{Object.values(JSON.parse(route.params.paramKey).message).map(item =>
Object.values(item.createdAt[0]).filter(actualDate =>
actualDate.includes(dateFilter) ? (
<Card mode="outlined" key={uuidv4()}>
<Title>{item?.createdAt[0].value}</Title>
<Button
style={{alignItems: 'flex-start'}}
color="#17E5C2"
icon={
infoVisible
? 'arrow-up-bold-outline'
: 'arrow-down-bold-outline'
}
mode="outlined"
onPress={() => {
handleInfo();
}}>
Ver detalhes
</Button>
{Object.keys(item).map(data => (
<Card.Content
key={uuidv4()}
style={infoVisible ? {display: 'flex'} : {display: 'none'}}
accessible={false}>
<Paragraph style={{fontWeight: 'bold'}}>{data}</Paragraph> // {data} is a string as I checked in console.log
<Paragraph>{item[data][0]?.value}</Paragraph>
</Card.Content>
))}
<Card.Actions>
<Button color={'#17E5C2'}>Edit</Button>
</Card.Actions>
</Card>
) : (
console.log('NO ACTUAL DATA') // When I change console.log to a react child like(<Text>test</Text>) the error appear's instantly
),
),
)}
</View>
The error appear's when I choose a date that has data.
I tried to put console.log besids react child , and when I put it appears to me the data.
So I tought the error could be in my react childs.
I tried to fix my jsx conditional , but not worked , also tried to remove some commas , but also not worked,
and I tried to use <> </> at the top and the end , but also not worked
Complete error message: Error: Text strings must be rendered within a <Text> component.
I tried the entire day so.... it's been dificulty , I want some tips about how to fix it.
One possible problem I can see from your code
Object.values(item.createdAt[0]).filter(actualDate => actualDate.includes(dateFilter) ? <YourComponent> : console.log('NO ACTUAL DATA'))
You're using filter instead of map for a ternary condition.
filter returns true/false value, so you shouldn't use it in this case
If you want to use it, the proper one could be
Object.values(item.createdAt[0]).filter(actualDate => actualDate.includes(dateFilter))
This error comes when you are not wrapping strings within the component or if you are you using some code formatter it sometimes add {" "} outside the components. Check for these scenarios within your components (P.s:- commenting out code component by component might save you some time)

How to pass data from Class to function in React Native array, firebase, stack navigator v5

Hay I am struggling on how to pass data that's in a class, to another react native component. I am able to display data on the same screen, however I want to have the user input some text and have it display on another screen.
1) Initial Screen: User presses button to navigate to text inputs, and will navigate back to this screen to view the list. Note: If I add the list here I get an error "undefined is not an object". Because I was not able to figure out how to PASS THE LISTARRAY variable to that screen.
export const GoalsScreen = ({ navigation }) => {
return (
<SafeAreaView style={styles.container}>
<Header>
{/* header title */}
<Text style={styles.goalText}> Expand your life</Text>
{/* add goal button goto stack */}
<TouchableOpacity onPress={() => navigation.navigate("AddGoal")} >
<Text style={styles.addBtn}> + </Text>
</TouchableOpacity>
</Header>
{/* Error here, need to get data from other screen */}
<FlatList
data={this.state.listArray}
renderItem={({ item, index }) => {
return (
<View>
<Text style={{ fontSize: 30 }}>{item.fireListGoal} </Text>
<Text style={{ fontSize: 20 }}>{item.fireListCat}</Text>
<Text style={{ fontSize: 15 }}> {item.fireListWhy}</Text>
</View>
);
}}
>
</FlatList>
</SafeAreaView>
);
}
2) List Screen: If I put the flatList here everything works, but I need to PASS THE DATA thats inputted here in the firebase real-time database and display it on the other screen shown above.
export class AddGoalList extends React.Component {
// state and defult values
constructor(props) {
super(props)
// set inital values
this.state = {
listArray: [],
goal: '',
category: 'Pick One',
why: '',
}
}
//triggers rerendering, put values in a JSON array
componentDidMount() {
goalsRef.on('value', (childSnapshot) => {
const listArray = [];
childSnapshot.forEach((doc) => {
listArray.push({
key: doc.key,
fireListGoal: doc.toJSON().fireListGoal,
fireListCat: doc.toJSON().fireListCat,
fireListWhy: doc.toJSON().fireListWhy
});
this.setState({
listArray: listArray.sort((a, b) => {
return (
a.fireListGoal < b.fireListGoal,
a.fireListCat < b.fireListCat,
a.fireListWhy < b.fireListWhy
);
}),
});
});
});
}
// when button pressed...
onGoal = ({ }) => {
// if form empty alert user
if (this.state.goal.trim() && this.state.why.trim() === '') {
alert("Please fill form.");
return;
}
if (this.state.category.valueOf() === 'Pick One') {
alert("Fill in all inputs.");
return;
}
// otherwise push data to firebase
goalsRef.push({
fireListGoal: this.state.goal,
fireListCat: this.state.category,
fireListWhy: this.state.why
});
}
render() {
return (
// KeyboardAvoidingView ==> prevent keyboard from overlapping
<KeyboardAvoidingView style={styles.container}>
<SafeAreaView>
<Text>Sparks your life!</Text>
{/* Goal title */}
<Text>What is your goal</Text>
<TextInput
placeholder="Enter your goal"
keyboardType='default'
onChangeText={
(text) => {
this.setState({ goal: text });
}
}
value={this.state.goal}
/>
{/* pick selected cetegory */}
<Text>Pick a Category</Text>
{/* picker component */}
<Picker
selectedValue={this.state.category}
onValueChange={(itemValue) => this.setState({ category: itemValue })}
>
<Picker.Item label="Pick One" value="Pick One" />
<Picker.Item label="Fitness" value="Fitness" />
<Picker.Item label="Health" value="Health" />
<Picker.Item label="Travel" value="Travel" />
<Picker.Item label="Wealth" value="Wealth" />
<Picker.Item label="Creativity" value="Creativity" />
<Picker.Item label="Skills" value="Skills" />
</Picker>
<Text>Why did you pick this goal?</Text>
<TextInput
placeholder="Enter your why"
keyboardType='default'
onChangeText={
(text) => {
this.setState({ why: text });
}
}
value={this.state.why}
/>
{/* nav back to My Goal list */}
<Button title="add goal" onPress={this.onGoal.bind(this)} />
</SafeAreaView>
{/* remove list here and add to other GoalsScreen */}
<FlatList
data={this.state.listArray}
renderItem={({ item, index }) => {
return (
<View>
<Text style={{fontSize: 30}}>{item.fireListGoal} </Text>
<Text style={{fontSize: 20}}>{item.fireListCat}</Text>
<Text style={{fontSize: 15}}> {item.fireListWhy}</Text>
</View>
);
}}
>
</FlatList>
</KeyboardAvoidingView>
);
}
}
I have tried to useState and pass data as a param but got errors, in able to use the variable navigation in a class..? Also tried to put it in a separate function and that did now work ether. I'll add my code bellow so you can take a look. Any suggestions and or references to any helpful docs would really be appreciated.
Would really appreciate some help, been trying to resolve this for the past few days with no luck. Many thanks!
If i understand the flow correctly, what you want is the following:
Initially, you have a first screen with a list of items (GoalsScreen). From there the user can open a new screen, where he can add items (AddGoalScreen). So, when the user goes back, you want him to see the updated list.
First of all, in the above code, the GoalsSrceen has not defined any state listArray, so that's why you get undefined error. You need to declare it just like you did in AddGoalScreen. Also, as i can see, the AddGoalScreen will no longer display this listArray, so you can simply move the goalsRef.on('value', ... subscription in the GoalsScreen. Doing so, each time you push to the firebase through AddGoalScreen, the on('value') subscription will be triggered inside GoalsScreen, and the GoalsScreen will rerender, keeping its state available. So you have your problem fixed

React. load different data arrays into slick slider

So at this stage I have a component in which I draw a slider, the photos of which are routes to certain rooms. The task now is to bring the slider to a separate page(component) ... which will open for the pages: rooms / news / promotions passing different arrays . Is it possible to do this in a reactor or is it a bad case and this task needs to be solved differently, I don’t even understand how to do it
<Slider ref={slider => (this.slider = slider)} {...settings}>
{RoomsService.rooms.map(room => {
return (
<div className="rooms_slider">
{room.title === 'Soon' ? (
<img src={room.img} />
) : (
<Link to={`/rooms/${room.id}`}>
<img src={room.img} />
</Link>
)}
</div>
);
})}
</Slider>
I am not quite sure what your question is, but you should be able to take everything you have done with the slider and abstract it out to a component that you simply pass props into.
const CustomSlider = ({rooms, settings}) => {
return (
<Slider ref={slider => (this.slider = slider)} {...settings}>
{rooms.map(room => {
return (
<div className="rooms_slider">
{room.title === 'Soon' ? (
<img src={room.img} />
) : (
<Link to={`/rooms/${room.id}`}>
<img src={room.img} />
</Link>
)}
</div>
);
})}
</Slider>
)
};
<CustomSlider rooms={[{title, img, id}]} settings={someSettingObj} />
From here you can conditionally render things based on the props available.

Selecting the correct item using material's GridList

I have a react-mobx code that's working with Material-UI and looks something like this:
render() {
// some consts declarations
return (
<div>
<img src={selectedPhoto} alt={'image title'} />
<GridList className={classes.gridList} cols={2.5}>
{photos.map(tile => (
<GridListTile key={tile} onClick={this.selectPhoto}>
<img src={tile} alt={'image title'} />
<GridListTileBar
classes={{
root: classes.titleBar,
title: classes.title
}}
/>
</GridListTile>
))}
</GridList>
</div>
);
}
This shows a list of photos. I would like to change the selected photo when the user clicks one of the GridListTile. The key (tile) is actually an image url.
As seen in the code, I tried adding onClick={this.selectPhoto} when the selectPhoto function looks like this:
selectPhoto = (photo) => {
this.props.rootStore.selectPhoto(photo);
}
The argument photo that is sent to the function is not tile (the image url) as I would like to have. How can I pass this argument to the function correctly?
You could create an inline arrow function and pass along your tile to selectPhoto:
photos.map(tile => (
<GridListTile key={tile} onClick={() => this.selectPhoto(tile)}>
<img src={tile} alt={'image title'} />
<GridListTileBar
classes={{
root: classes.titleBar,
title: classes.title
}}
/>
</GridListTile>
))

Categories

Resources