213 lines
7.8 KiB
JavaScript
213 lines
7.8 KiB
JavaScript
import Card from "./card";
|
|
import {useEffect, useState} from "react";
|
|
import {Pressable, Image, Linking, View} from "react-native";
|
|
|
|
// Icons
|
|
import TickActive from '../assets/ph_check-fill.svg'
|
|
import TickDanger from '../assets/tick_danger.svg'
|
|
import TickSuccess from '../assets/tick_success.svg'
|
|
import Chevron from '../assets/bi_chevron.svg'
|
|
import TickError from '../assets/codicon_error.svg'
|
|
|
|
|
|
const Tooltip = ({timeTill}) => {
|
|
const d = new Date(timeTill)
|
|
return (
|
|
<View style={{backgroundColor: "#ecd98d", position: "absolute", top: 0, right: 0, padding:10, borderRadius: 8}}>
|
|
<Card.TextSmall>{`${d.getDate()}.${d.getMonth() + 1}.${d.getFullYear()}`}</Card.TextSmall>
|
|
<Card.TextSmall>{`${d.toLocaleTimeString()}`}</Card.TextSmall>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
const Task = ({id, status, title, description, time_till: timeTill, onPress, time_finished: timeFinished, imageType, navi, type}) => {
|
|
const [intervalId, setIntervalId] = useState(null);
|
|
|
|
const [leastTime, setLeastTime] = useState("");
|
|
|
|
const variantSelection = () => {
|
|
if (type && type === 'event') {
|
|
switch (status) {
|
|
case "active":
|
|
return 'default'
|
|
case "completed":
|
|
return 'success'
|
|
}
|
|
}
|
|
|
|
switch (status) {
|
|
case "active":
|
|
if (new Date().getTime() <= new Date(timeTill)) {
|
|
return "default"
|
|
}
|
|
return "error"
|
|
|
|
case "uncompleted":
|
|
return "error"
|
|
|
|
case "completed":
|
|
if (new Date(timeFinished).getTime() <= new Date(timeTill).getTime()) {
|
|
return "success"
|
|
}
|
|
return "danger"
|
|
}
|
|
}
|
|
|
|
|
|
const countDays = () => {
|
|
const date = new Date(timeTill);
|
|
let now = !!timeFinished ? new Date(timeFinished) : new Date();
|
|
|
|
const diffTime = Math.abs(date - now);
|
|
return Math.floor(diffTime / (1000 * 60 * 60 * 24));
|
|
}
|
|
|
|
const countHours = () => {
|
|
const date = new Date(timeTill);
|
|
let now = !!timeFinished ? new Date(timeFinished) : new Date();
|
|
|
|
if (now.getTime() <= date.getTime()) {
|
|
now = now.getTime() + countDays() * 24 * 60 * 60 * 1000;
|
|
} else {
|
|
now = now.getTime() - countDays() * 24 * 60 * 60 * 1000;
|
|
}
|
|
|
|
const diffTime = Math.abs(date - now);
|
|
return Math.floor(diffTime / (1000 * 60 * 60));
|
|
}
|
|
|
|
const countMinutes = () => {
|
|
const date = new Date(timeTill);
|
|
let now = !!timeFinished ? new Date(timeFinished) : new Date();
|
|
|
|
if (now.getTime() <= date.getTime()) {
|
|
now = now.getTime() + countDays() * 24 * 60 * 60 * 1000 + countHours() * 60 * 60 * 1000;
|
|
} else {
|
|
now = now.getTime() - countDays() * 24 * 60 * 60 * 1000 - countHours() * 60 * 60 * 1000;
|
|
}
|
|
const diffTime = Math.abs(date - now);
|
|
return Math.floor(diffTime / (1000 * 60));
|
|
}
|
|
|
|
const absTime = () => {
|
|
const query = {
|
|
start: (d, idx) => {
|
|
const val = +(d.split('').slice(-2).join(''))
|
|
if (val > 10 && val < 20) return [`${d} дней`, `${d} часов`, `${d} минут`][idx]
|
|
return query['1'](d, idx)
|
|
}
|
|
,
|
|
'1': (d, idx) => {
|
|
const val = +(d.split('').slice(-1))
|
|
if (val === 1) return [`${d} день`, `${d} час`, `${d} минута`][idx]
|
|
return query['2-4'](d, idx)
|
|
},
|
|
'2-4': (d, idx) => {
|
|
const val = +(d.split('').slice(-1))
|
|
if (val > 1 && val < 5) return [`${d} дня`, `${d} часа`, `${d} минуты`][idx]
|
|
return [`${d} дней`, `${d} часов`, `${d} минут`][idx]
|
|
},
|
|
}
|
|
|
|
let days = query.start(`${countDays()}`, 0)
|
|
const hours = query.start(`${countHours()}`, 1)
|
|
const minutes = query.start(`${countMinutes()}`, 2)
|
|
|
|
|
|
setLeastTime(`${days} ${hours} ${minutes}`)
|
|
}
|
|
|
|
useEffect(() => {
|
|
if (intervalId !== null) {
|
|
clearInterval(intervalId)
|
|
setIntervalId(null)
|
|
}
|
|
absTime()
|
|
if (status !== 'active') return;
|
|
setIntervalId(setInterval(() => absTime(), 1000))
|
|
}, [timeTill, timeFinished]);
|
|
|
|
const SelectImage = () => {
|
|
if (imageType === 'chevron') {
|
|
return <Chevron style={{transform: [{rotate: '270deg'}]}}/>
|
|
}
|
|
|
|
switch (status) {
|
|
case "active":
|
|
return <TickActive/>
|
|
case "completed":
|
|
if (new Date(timeFinished).getTime() <= new Date(timeTill).getTime()) {
|
|
return <TickSuccess/>
|
|
}
|
|
return <TickDanger/>
|
|
case "uncompleted":
|
|
return <TickError/>
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Pressable onPress={onPress}>
|
|
<Card.Block variant={variantSelection()}
|
|
image={<SelectImage/>}
|
|
tooltip={type !== 'event' && <Tooltip timeTill={timeTill} />}>
|
|
<Card.Header>
|
|
{title.split("|").map(txt => {
|
|
|
|
if (txt.replace("<b>", '').replace("</b>", '') !== txt) {
|
|
return <Card.TitleNumber>{txt.replace('<b>', '').replace('</b>', '')}</Card.TitleNumber>
|
|
}
|
|
else {
|
|
return <Card.TextSmall>{txt}</Card.TextSmall>
|
|
}
|
|
|
|
})}
|
|
</Card.Header>
|
|
|
|
<Card.Body>
|
|
{!!description && <Card.TextSmall>{description}</Card.TextSmall>}
|
|
{!!navi && <Pressable style={{
|
|
borderColor: "#ECA704",
|
|
borderWidth: 2,
|
|
borderRadius: 40,
|
|
padding: 18,
|
|
display: 'flex',
|
|
flexDirection: "row",
|
|
alignItems: 'center',
|
|
marginBottom: 10
|
|
}}
|
|
onPress={() => Linking.openURL(`yandexnavi://build_route_on_map?lat_to=${navi.lat}&lon_to=${navi.lon}`)}>
|
|
<Image source={require('../assets/yandexNavi.png')} width={25} height={25}
|
|
style={{marginRight: 10}}></Image>
|
|
<Card.TextSmall style={{color: "#000"}}>Открыть в яндекс картах</Card.TextSmall>
|
|
</Pressable>}
|
|
|
|
{
|
|
type !== 'event' && status === 'active' && new Date(timeTill) >= new Date() &&
|
|
<Card.TextSmall>Осталось времени: </Card.TextSmall>
|
|
}
|
|
|
|
{
|
|
type !== 'event' && status === 'active' && new Date(timeTill) < new Date() &&
|
|
<Card.TextSmall>Опоздание: </Card.TextSmall>
|
|
}
|
|
|
|
{
|
|
type !== 'event' && status === 'completed' && new Date(timeFinished) <= new Date(timeTill) &&
|
|
<Card.TextSmall>Завершено раньше на: </Card.TextSmall>
|
|
}
|
|
{
|
|
type !== 'event' && status === 'completed' && new Date(timeFinished) > new Date(timeTill) &&
|
|
<Card.TextSmall>Завершено c опозданием на: </Card.TextSmall>
|
|
}
|
|
{
|
|
type !== 'event' && status !== 'uncompleted' && <Card.TitleExtra>{leastTime}</Card.TitleExtra>
|
|
}
|
|
|
|
</Card.Body>
|
|
</Card.Block>
|
|
</Pressable>
|
|
)
|
|
}
|
|
|
|
|
|
export default Task; |