|
|
@@ -0,0 +1,138 @@ |
|
|
|
import React from 'react'; |
|
|
|
|
|
|
|
function PhoneSymbol(props) { |
|
|
|
if (props.incoming) { |
|
|
|
return ( |
|
|
|
<svg width="1em" height="1em" viewBox="0 0 16 16" className="bi |
|
|
|
bi-telephone-inbound-fill in-phone" fill="currentColor" |
|
|
|
xmlns="http://www.w3.org/2000/svg"> <path fillRule="evenodd" |
|
|
|
d="M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 |
|
|
|
2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 |
|
|
|
.178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 |
|
|
|
0 0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 |
|
|
|
1.034c-.74.74-1.846 1.065-2.877.702a18.634 18.634 0 0 1-7.01-4.42 |
|
|
|
18.634 18.634 0 0 |
|
|
|
1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877L1.885.511zM15.854.146a.5.5 |
|
|
|
0 0 1 0 .708L11.707 5H14.5a.5.5 0 0 1 0 1h-4a.5.5 0 0 |
|
|
|
1-.5-.5v-4a.5.5 0 0 1 1 0v2.793L15.146.146a.5.5 0 0 1 .708 0z"/> |
|
|
|
</svg> |
|
|
|
) |
|
|
|
|
|
|
|
} else { |
|
|
|
return ( |
|
|
|
<svg width="1em" height="1em" viewBox="0 0 16 16" className="bi |
|
|
|
bi-telephone-outbound-fill out-phone" fill="currentColor" |
|
|
|
xmlns="http://www.w3.org/2000/svg"> <path fillRule="evenodd" |
|
|
|
d="M1.885.511a1.745 1.745 0 0 1 2.61.163L6.29 |
|
|
|
2.98c.329.423.445.974.315 1.494l-.547 2.19a.678.678 0 0 0 |
|
|
|
.178.643l2.457 2.457a.678.678 0 0 0 .644.178l2.189-.547a1.745 1.745 0 |
|
|
|
0 1 1.494.315l2.306 1.794c.829.645.905 1.87.163 2.611l-1.034 |
|
|
|
1.034c-.74.74-1.846 1.065-2.877.702a18.634 18.634 0 0 1-7.01-4.42 |
|
|
|
18.634 18.634 0 0 |
|
|
|
1-4.42-7.009c-.362-1.03-.037-2.137.703-2.877L1.885.511zM11 .5a.5.5 0 |
|
|
|
0 1 .5-.5h4a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-1 0V1.707l-4.146 4.147a.5.5 |
|
|
|
0 0 1-.708-.708L14.293 1H11.5a.5.5 0 0 1-.5-.5z"/> |
|
|
|
</svg> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function DetailSymbol() { |
|
|
|
return ( |
|
|
|
<svg width="1em" height="1em" viewBox="0 0 16 16" className="bi |
|
|
|
bi-chevron-right detail icon" fill="currentColor" |
|
|
|
xmlns="http://www.w3.org/2000/svg"> <path strokeWidth="1px" |
|
|
|
fillRule="evenodd" d="M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 |
|
|
|
1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 |
|
|
|
1 0-.708z"/> </svg> |
|
|
|
) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
function Seperator(props) { |
|
|
|
if (props.index == 0 || props.stack[props.index].time[0].toLocaleDateString() != |
|
|
|
props.stack[props.index - 1].time[0].toLocaleDateString()) { |
|
|
|
return (<div className="date"><h3> |
|
|
|
{props.stack[props.index].time[0].toLocaleDateString()} |
|
|
|
</h3></div>) |
|
|
|
} |
|
|
|
return <span></span> |
|
|
|
} |
|
|
|
|
|
|
|
// The component used for retrieving, sorting, and rendering calls. |
|
|
|
function Feed() { |
|
|
|
// The function could first make an AJAX request for the list of calls over |
|
|
|
// the last 14 days. Here, it would then sort the list by collapsing calls |
|
|
|
// from the same caller within the day into a single entry in a stack. A |
|
|
|
// sorted mock stack is used here for brevity. |
|
|
|
|
|
|
|
const stack = [ |
|
|
|
{number: 4169932232, time: [ |
|
|
|
new Date(2021, 10, 19, 8, 21), |
|
|
|
new Date(2021, 10, 19, 7), |
|
|
|
new Date(2021, 10, 19, 4, 44) |
|
|
|
], |
|
|
|
length: [5, 15, 12], incoming: true, name: "John McNiel",}, |
|
|
|
|
|
|
|
{number: 3135553298, time: [ |
|
|
|
new Date(2021, 10, 18, 21, 41), |
|
|
|
new Date(2021, 10, 18, 20, 0), |
|
|
|
], |
|
|
|
length: [11, 21], incoming: false, name: "Peter Turcot"}, |
|
|
|
|
|
|
|
{number: 6139928847, time: [ |
|
|
|
new Date(2021, 10, 18, 21, 51), |
|
|
|
new Date(2021, 10, 18, 19, 10, 0), |
|
|
|
new Date(2021, 10, 18, 16, 8) |
|
|
|
], |
|
|
|
length: [5, 15, 12], incoming: true, name: null}, |
|
|
|
|
|
|
|
{number: 6136643277, time: [ |
|
|
|
new Date(2021, 10, 18, 7, 51), |
|
|
|
], |
|
|
|
length: [0], |
|
|
|
incoming: true, name: "John McNiel"}, |
|
|
|
|
|
|
|
{number: 6138899255, time: [ |
|
|
|
new Date(2021, 10, 16, 10, 33), |
|
|
|
new Date(2021, 10, 16, 16, 8) |
|
|
|
], |
|
|
|
length: [0, 7], |
|
|
|
incoming: false, name: null}, |
|
|
|
{number: 4167753324, time: [ |
|
|
|
new Date(2021, 10, 18, 16, 51), |
|
|
|
new Date(2021, 10, 18, 16, 8)], length: [0, 0], |
|
|
|
incoming: false, name: "Amy White"} |
|
|
|
] |
|
|
|
|
|
|
|
let dates = stack.map((entry) => { |
|
|
|
return entry.time[0] |
|
|
|
}) |
|
|
|
|
|
|
|
let entries = stack.map((entry, index) => { |
|
|
|
return ( |
|
|
|
<React.Fragment> |
|
|
|
<Seperator stack={stack} index={index}/> |
|
|
|
<li key={index}> |
|
|
|
<h4>{entry.name ? entry.name : entry.number} |
|
|
|
<span>{entry.time.length}</span> |
|
|
|
<PhoneSymbol incoming={entry.incoming}/> |
|
|
|
</h4> |
|
|
|
<small>{entry.time[0].toLocaleTimeString([], |
|
|
|
{hour: '2-digit', minute: '2-digit'})} |
|
|
|
</small> |
|
|
|
<DetailSymbol></DetailSymbol> |
|
|
|
</li> |
|
|
|
</React.Fragment> |
|
|
|
) |
|
|
|
}) |
|
|
|
return ( |
|
|
|
// A call length of 0 is a missed or unanswered call |
|
|
|
<ul className="calls"> |
|
|
|
{entries} |
|
|
|
</ul> |
|
|
|
) |
|
|
|
} |
|
|
|
|
|
|
|
export default Feed; |