mirror of
https://github.com/bellingcat/ukraine-timemap.git
synced 2026-06-13 05:48:36 +03:00
Cleaning technical debt (#192)
* abstract Space component to switch out Map * basic viewing possible * restructure components dir * all jsx --> js * App.jsx --> App.js * comment out 3d for now
This commit is contained in:
16
src/components/controls/atoms/NarrativeAdjust.js
Normal file
16
src/components/controls/atoms/NarrativeAdjust.js
Normal file
@@ -0,0 +1,16 @@
|
||||
import React from "react";
|
||||
|
||||
const Adjust = ({ isDisabled, direction, onClickHandler }) => {
|
||||
return (
|
||||
<div
|
||||
className={`narrative-adjust ${direction}`}
|
||||
onClick={!isDisabled ? onClickHandler : null}
|
||||
>
|
||||
<i className={`material-icons ${isDisabled ? "disabled" : ""}`}>
|
||||
{`chevron_${direction}`}
|
||||
</i>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Adjust;
|
||||
40
src/components/controls/atoms/NarrativeCard.js
Normal file
40
src/components/controls/atoms/NarrativeCard.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import React from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { selectActiveNarrative } from "../../../selectors";
|
||||
|
||||
function NarrativeCard({ narrative }) {
|
||||
// no display if no narrative
|
||||
const { steps, current } = narrative;
|
||||
|
||||
if (steps[current]) {
|
||||
return (
|
||||
<div className="narrative-info">
|
||||
<div className="narrative-info-header">
|
||||
<div className="count-container">
|
||||
<div className="count">
|
||||
{current + 1}/{steps.length}
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h3>{narrative.label}</h3>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* <i className='material-icons left'>location_on</i> */}
|
||||
{/* {_renderActions(current, steps)} */}
|
||||
<div className="narrative-info-desc">
|
||||
<p>{narrative.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
narrative: selectActiveNarrative(state),
|
||||
};
|
||||
}
|
||||
export default connect(mapStateToProps)(NarrativeCard);
|
||||
14
src/components/controls/atoms/NarrativeClose.js
Normal file
14
src/components/controls/atoms/NarrativeClose.js
Normal file
@@ -0,0 +1,14 @@
|
||||
import React from "react";
|
||||
|
||||
const Close = ({ onClickHandler, closeMsg }) => {
|
||||
return (
|
||||
<div className="narrative-close" onClick={onClickHandler}>
|
||||
<button className="side-menu-burg is-active">
|
||||
<span />
|
||||
</button>
|
||||
<div className="close-text">{closeMsg}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Close;
|
||||
62
src/components/controls/atoms/SearchRow.jsx
Normal file
62
src/components/controls/atoms/SearchRow.jsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import React from "react";
|
||||
|
||||
const SearchRow = ({ query, eventObj, onSearchRowClick }) => {
|
||||
const { description, location, date } = eventObj;
|
||||
function getHighlightedText(text, highlight) {
|
||||
// Split text on highlight term, include term itself into parts, ignore case
|
||||
const parts = text.split(new RegExp(`(${highlight})`, "gi"));
|
||||
return (
|
||||
<span>
|
||||
{parts.map((part) =>
|
||||
part.toLowerCase() === highlight.toLowerCase() ? (
|
||||
<span style={{ backgroundColor: "yellow", color: "black" }}>
|
||||
{part}
|
||||
</span>
|
||||
) : (
|
||||
part
|
||||
)
|
||||
)}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function getShortDescription(text, searchQuery) {
|
||||
const regexp = new RegExp(
|
||||
`(([^ ]* ){0,6}[a-zA-Z]*${searchQuery.toLowerCase()}[a-zA-Z]*( [^ ]*){0,5})`,
|
||||
"gm"
|
||||
);
|
||||
const parts = text.toLowerCase().match(regexp);
|
||||
for (let x = 0; x < (parts ? parts.length : 0); x++) {
|
||||
parts[x] = "..." + parts[x];
|
||||
}
|
||||
const firstLine = [text.match("(([^ ]* ){0,10})", "m")[0]];
|
||||
return parts || firstLine;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="search-row" onClick={() => onSearchRowClick([eventObj])}>
|
||||
<div className="location-date-container">
|
||||
<div className="date-container">
|
||||
<i className="material-icons">event</i>
|
||||
<p>{getHighlightedText(date, query)}</p>
|
||||
</div>
|
||||
<div className="location-container">
|
||||
<i className="material-icons">location_on</i>
|
||||
<p>{getHighlightedText(location, query)}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
{getShortDescription(description, query).map((match) => {
|
||||
return (
|
||||
<span>
|
||||
{getHighlightedText(match, query)}...
|
||||
<br />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchRow;
|
||||
Reference in New Issue
Block a user