Skip to content

Commit

Permalink
feat: impliment newlines in multiline data
Browse files Browse the repository at this point in the history
In this PR, we resolve the css conflicts which would use css rules to show / render new lines.
Implients a data normalization technique to convert new line chars `\n` to HTML elements `<br />` in the UI Layer.
Adds env variable for limiting & showing trip introduction on the the trips list.
Adds a new util method `toBr` for conversion.
refactor: streamline docs for env files.
  • Loading branch information
awaisdar001 committed Oct 14, 2021
1 parent 93608eb commit 4c62b9b
Show file tree
Hide file tree
Showing 12 changed files with 83 additions and 53 deletions.
3 changes: 3 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
REACT_APP_BASE_URL=''
REACT_APP_GOOGLE_API_URL=''
REACT_APP_LIMIT_TRIP_INTRO_TO_CHAR=500
1 change: 1 addition & 0 deletions .env.production
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NODE_ENV='production'
REACT_APP_BASE_URL='http://www.destinationpak.com'
REACT_APP_GOOGLE_API_URL=''
REACT_APP_LIMIT_TRIP_INTRO_TO_CHARS=600
1 change: 1 addition & 0 deletions .env.test
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
NODE_ENV='test'
BASE_URL='http://localhost:8003'
REACT_APP_GOOGLE_API_URL=''
REACT_APP_LIMIT_TRIP_INTRO_TO_CHARS=600
1 change: 0 additions & 1 deletion src/static/styles/css/Trips.css
Original file line number Diff line number Diff line change
Expand Up @@ -695,7 +695,6 @@
}

.timeline-with-label .item .cbp_tmlabel p {
white-space: pre-line;
margin-top: 1rem;
margin-bottom: 1rem;
}
Expand Down
13 changes: 6 additions & 7 deletions src/static/styles/scss/Trips.scss
Original file line number Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@
@extend .input-with-icon-default;
text-transform: capitalize;
&:focus {
color: #303030;
color: $theme-black;
}
&:-moz-placeholder {
color: inherit;
Expand All @@ -556,7 +556,7 @@
.input-with-icon input[type="email"] {
@extend .input-with-icon-default;
&:focus {
color: #303030;
color: $theme-black;
}
&:-moz-placeholder {
color: inherit;
Expand All @@ -572,7 +572,7 @@
.input-with-icon input[type="password"] {
@extend .input-with-icon-default;
&:focus {
color: #303030;
color: $theme-black;
}
&:-moz-placeholder {
color: inherit;
Expand All @@ -588,7 +588,7 @@
.input-with-icon input[type="number"] {
@extend .input-with-icon-default;
&:focus {
color: #303030;
color: $theme-black;
}
&:-moz-placeholder {
color: inherit;
Expand All @@ -608,7 +608,7 @@

@extend .input-with-icon-default;
&:focus {
color: #303030;
color: $theme-black;
}
&:-moz-placeholder {
color: inherit;
Expand Down Expand Up @@ -694,7 +694,6 @@
display: none;
}
p {
white-space: pre-line;
margin-top: 1rem;
margin-bottom: 1rem;
}
Expand Down Expand Up @@ -739,7 +738,7 @@
margin-right: 9px;
font-size: 15px;
line-height: 1.667em;
color: #303030;
color: $theme-black;
font-weight: 700;
}
.rating-wrapper {
Expand Down
1 change: 1 addition & 0 deletions src/static/styles/scss/_config.scss
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ $background-grey: #f3f3f3;
$border-color: #ddd;
$text-color: #555;
$theme-gray: #515151;
$theme-black: #303030;
$footer-color: #272727;
$theme-green: #7ed12d;
$theme-green-d1: #72c02c;
Expand Down
2 changes: 1 addition & 1 deletion src/static/styles/scss/_custom.scss
Original file line number Diff line number Diff line change
Expand Up @@ -1673,7 +1673,7 @@ textarea.theme-textarea {
transition: border-color 175ms cubic-bezier(0.18, 0.43, 0.58, 1);

&:focus {
color: #303030;
color: $theme-black;
border-color: #808285;
}
}
Expand Down
30 changes: 22 additions & 8 deletions src/trips/data/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ import {
camelCaseObject,
DateUtils,
getRatingFeedback,
normalizeBySlug, normalizeLocation,
normalizeBySlug,
normalizeLocation,
normalizeUser,
toBr,
transformQueryString,
} from '../../utils';

Expand Down Expand Up @@ -68,7 +70,7 @@ const createTripSchedules = ({ type, options }) => {
};

/**
* Fetches timeline items.
* Fetches trip list items.
* @returns {Promise<[{}]>}
*/
export async function getTripItems(options) {
Expand Down Expand Up @@ -98,36 +100,48 @@ const normalizeTripsListData = (data) => {
const normalizedData = {
items: data.results.map((trip) => normalizeTrip(trip)),
categories: [].concat(...categories, primaryCategories),
users: users,
facilities: [].concat(...facilities),
hosts,
locations: [].concat(locations, startingLocations, destinations),
hosts,
metaData: {
current: data.current,
pages: data.pages,
next: data.next,
previous: data.previous,
total: data.count,
},
users: users,
};

return camelCaseObject(normalizedData);
};

const normalizeTrip = (trip) => ({
...trip,
categories: trip.categories.map((category) => category.slug),
cancellation_policy: trip.cancellation_policy,
primary_category: trip.primary_category?.slug,
createdBy: trip.created_by.username,
destination: trip.destination?.slug,
description: toBr(trip.description),
introduction: _.truncate(trip.description, {
length: process.env.REACT_APP_LIMIT_TRIP_INTRO_TO_CHAR,
separator: '.',
omission: '. [...]',
}),
facilities: trip.facilities.map((facility) => facility.slug),
gear: trip.gear,
host: trip.host.slug,
locations: trip.locations.map((location) => location.slug),
destination: trip.destination?.slug,
starting_location: trip.starting_location?.slug,
gear: trip.gear,
minPrice: trip.trip_availability.price,
primary_category: trip.primary_category?.slug,
starting_location: trip.starting_location?.slug,
trip_itinerary: trip.trip_itinerary.map((day) => ({
...day,
description: toBr(day.description),
})),
});


const normalizeHost = (host) => {
const tripHostRating = host.rating;

Expand Down
15 changes: 7 additions & 8 deletions src/trips/trip-item/TourPlan.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react';

const TripItem = ({ day, setHeading }) => {
import { createMarkup, NewLineToBr, toBr } from '../../utils';

const TripItinerary = ({ day, setHeading }) => {
const { heading, description } = day;
return (
<div className="item">
Expand All @@ -20,22 +22,19 @@ const TripItem = ({ day, setHeading }) => {

<div className="cbp_tmlabel">
{setHeading && <h2>{heading}</h2>}
{/*<p dangerouslySetInnerHTML={createMarkup(day.description)} />*/}

<p>{description}</p>
<p dangerouslySetInnerHTML={createMarkup(description)} />
</div>
</div>
)
}

);
};

function TourPlan({ tripItinerary }) {
return (
<div id="tour-plan" className="wrapper-block">
<h3 className="h3">Tour Plan</h3>
<div id="plan-timeline" className="timeline-with-label">
{tripItinerary.map((day, idx) => (
<TripItem key={`plan-${idx}`} day={day} setHeading={false} />
<TripItinerary key={`plan-${idx}`} day={day} setHeading={false} />
))}
</div>
</div>
Expand Down
51 changes: 29 additions & 22 deletions src/trips/trip-item/TripItem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import React, {useEffect} from 'react';
import {Col, Container, Row} from 'react-bootstrap';
import {useDispatch, useSelector} from 'react-redux';

import {NewLineToBr} from '../../utils';
import {TripItemPlaceholder} from '../Placeholders';
import {Title, TitlePrice} from '../TripCommon';
import { createMarkup, NewLineToBr, toBr } from '../../utils';
import { TripItemPlaceholder } from '../Placeholders';
import { Title, TitlePrice } from '../TripCommon';
import BookingSideBar from './booking-sidebar';
import {fetchTrip} from './data/thunks';
import { fetchTrip } from './data/thunks';
import {
CancellationPolicy,
Carousel,
Expand All @@ -17,9 +17,9 @@ import {
TripHighlights,
TripHost,
} from './index';
import {TripDetails} from './trip-details';
import { TripDetails } from './trip-details';

export default function TripItem({slug}) {
export default function TripItem({ slug }) {
const dispatch = useDispatch();

useEffect(() => {
Expand All @@ -30,7 +30,7 @@ export default function TripItem({slug}) {
const trip = useSelector((state) => state.tripItem.trip);

if (isLoading) {
return <TripItemPlaceholder/>;
return <TripItemPlaceholder />;
}
const tripLocations = {
destination: trip.destination,
Expand All @@ -53,31 +53,38 @@ export default function TripItem({slug}) {

return (
<div className="dp-trips">
<Carousel/>
<Carousel />
<Container fluid>
<TripHeader/>
<TripHeader />
<div className="trip-wrapper">
<Row>
<Col lg={9}>
<div className="item-detail">
<Title className="float-left" name={trip.name} url="#"/>
<TitlePrice className={'float-right'} tripMinPrice={trip.minPrice}/>
<TripHighlights trip={tripHighlights}/>
<hr/>
<Title className="float-left" name={trip.name} url="#" />
<TitlePrice className={'float-right'} tripMinPrice={trip.minPrice} />
<TripHighlights trip={tripHighlights} />
<hr />
<div className="item-description">
<NewLineToBr>{trip.description}</NewLineToBr>
<p dangerouslySetInnerHTML={createMarkup(trip.description)} />
</div>
<TripDetails trip={tripDetail}/>
<TourPlan tripItinerary={trip.tripItinerary}/>
<GoogleLocation trip={tripLocations}/>
<CancellationPolicy cancellationPolicy={trip.cancellationPolicy}/>
<TripHost host={trip.host}/>
<PostComment/>

<TripDetails trip={tripDetail} />
<TourPlan tripItinerary={trip.tripItinerary} />
<GoogleLocation trip={tripLocations} />
<CancellationPolicy cancellationPolicy={trip.cancellationPolicy} />
<TripHost host={trip.host} />
<PostComment />
</div>
</Col>
<Col lg={3}>
<BookingSideBar tripDates={trip.schedules}/>
<a href={trip.metadata.url} className="btn btn-success btn-block btn-lg" target='_blank'>
<BookingSideBar tripDates={trip.schedules} />
{/*TODO: delete it when we release.*/}
<a
href={trip.metadata.url}
className="btn btn-success btn-block btn-lg"
target="_blank"
rel="noreferrer"
>
Go to trip details
</a>
</Col>
Expand Down
10 changes: 4 additions & 6 deletions src/trips/trips-list/content/TripCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,11 @@ const TripCard = ({trip}) => {
</div>
</div>
<div className="item-detail">
<Title name={trip.name} url={tripUrl}/>
<TitlePrice tripMinPrice={trip.minPrice}/>
<div className="item-description">
<TripDescription/>
</div>
<Title name={trip.name} url={tripUrl} />
<TitlePrice tripMinPrice={trip.minPrice} />
<div className="item-description">{trip.introduction}</div>

<ReadOnlyRating rating={hostRating.value} ratedBy={hostRating.ratedBy}/>
<ReadOnlyRating rating={hostRating.value} ratedBy={hostRating.ratedBy} />

<Metadata
className="mt-4"
Expand Down
8 changes: 8 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ export function snakeCaseObject(object) {
export const getDateFromMilliSec = (number, format = DateFormats.DayMonth) =>
moment(number).format(format);

/*
* Convert all returns into HTML line break elements.
* @param data{str} object
*/
export const toBr = (data) => {
return data.replace(/(?:\r\n|\r|\n)/g, '<br />');
};

export const NewLineToBr = ({ children = '' }) => {
return children.split('\n').reduce((arr, line, index) => {
const addP = <p key={index}>{line}</p>;
Expand Down

0 comments on commit 4c62b9b

Please sign in to comment.