Add typescript. Idle function to load defalt screen
This commit is contained in:
parent
2ccd31d53b
commit
857ba29540
8 changed files with 679 additions and 378 deletions
|
|
@ -9,11 +9,16 @@
|
|||
"@testing-library/jest-dom": "^5.16.5",
|
||||
"@testing-library/react": "^13.3.0",
|
||||
"@testing-library/user-event": "^13.5.0",
|
||||
"@types/jest": "^29.5.12",
|
||||
"@types/node": "^20.12.7",
|
||||
"@types/react": "^18.3.1",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"axios": "^0.27.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1",
|
||||
"simple-xml-to-json": "^1.2.2",
|
||||
"typescript": "^5.4.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
{
|
||||
|
||||
width: 100%;
|
||||
height: 150vmax;
|
||||
height: 200vmax;
|
||||
/* height: 5000px; */
|
||||
pointer-events: none;
|
||||
border: 0;
|
||||
|
|
|
|||
365
src/App.js
365
src/App.js
|
|
@ -1,365 +0,0 @@
|
|||
import React, {useState, useEffect, useRef} from 'react';
|
||||
import axios from 'axios'
|
||||
import {Box, Typography, Paper, Container, Button} from '@mui/material';
|
||||
import './App.css';
|
||||
|
||||
const {convertXML} = require("simple-xml-to-json");
|
||||
|
||||
const MAIN_HEADER_FONT_SIZE = 50;
|
||||
const headerFontSize = 20;
|
||||
const DATA_FONT_SIZE = 42;
|
||||
const TEMPERATURE_URL = "http://10.0.0.106:3000/gettemperature";
|
||||
const DEPARTURES_URL = 'http://10.0.0.106:3000/getdepartures';
|
||||
const SOKOLOV_RSS_URL = 'https://www.sokolov.cz/rss/';
|
||||
const DAYS_OF_WEEK = ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"];
|
||||
let msToMidnight = null;
|
||||
let updateDayOfWeek;
|
||||
const OPTIONS = { hour12: false };
|
||||
let sokolovFeed;
|
||||
|
||||
// colors in sokolov website
|
||||
const LOGO_COLOR = '#82c55b' // green
|
||||
const FONT_COLOR = '#00367b';
|
||||
|
||||
|
||||
function App() {
|
||||
|
||||
var [date, setDate] = useState(new Date());
|
||||
var [temperature, setTemperature] = useState("?");
|
||||
var [departures, setDepartures] = useState([]);
|
||||
var [dayOfWeek, setDayOfWeek] = useState('');
|
||||
var [feedData, setFeedData] = useState([{title: "Chyba stažení dat, kontaktujte prosím administrátora", description:"", link:"", pubDate: new Date()}]);
|
||||
var [chosenArticle, setChosenArticle] = useState({clicked: false, url: ""});
|
||||
|
||||
// to assure, that website in iframe loads at the top
|
||||
const iframeRef = useRef(null);
|
||||
//to assure, that feed loads at the top
|
||||
const containerRef = useRef(null);
|
||||
|
||||
const executeScroll = () => {
|
||||
iframeRef.current.scrollIntoView(true);
|
||||
}
|
||||
|
||||
useEffect(()=> {
|
||||
!chosenArticle.clicked && containerRef.current.scrollIntoView({ behavior: 'smooth' });
|
||||
}, [chosenArticle])
|
||||
|
||||
function updateDate() {
|
||||
setDate(new Date());
|
||||
}
|
||||
|
||||
// go back to rss feed page
|
||||
const resetWeb = () => {
|
||||
setChosenArticle({clicked: false, url: ""});
|
||||
}
|
||||
|
||||
function getTemperature() {
|
||||
axios(TEMPERATURE_URL, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
}})
|
||||
.then(response => {
|
||||
let t = parseFloat(response.data);
|
||||
//console.log(t);
|
||||
if(isNaN(t)) return;
|
||||
|
||||
setTemperature(t);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function getDepartures() {
|
||||
axios(DEPARTURES_URL, {
|
||||
headers: {
|
||||
'Access-Control-Allow-Origin': '*',
|
||||
}})
|
||||
.then(response => {
|
||||
const departures = response.data;
|
||||
setDepartures(departures);
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function milisecondsToMidnight() {
|
||||
var midnight = new Date();
|
||||
midnight.setHours(24,0,0,0);
|
||||
|
||||
var now = new Date();
|
||||
var msToMidnight = midnight - now; //miliseconds to midnight
|
||||
return msToMidnight + 2000; // just to make sure day change after midnight, I am adding 2 seconds
|
||||
}
|
||||
|
||||
// we find out how long time is to midnight. after midnight is reached, getDay function is called and name of day is changed (streda --> ctvrtek).
|
||||
function getDay() {
|
||||
clearInterval(updateDayOfWeek);
|
||||
const date = new Date();
|
||||
setDayOfWeek(DAYS_OF_WEEK[date.getDay()]);
|
||||
|
||||
msToMidnight = milisecondsToMidnight();
|
||||
console.log('setDay called, ms to midnight', msToMidnight);
|
||||
updateDayOfWeek = setInterval(getDay, msToMidnight);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
updateDate();
|
||||
getTemperature();
|
||||
getDepartures();
|
||||
getDay();
|
||||
|
||||
var timer = setInterval(updateDate, 1000);
|
||||
var timerTemperature = setInterval(getTemperature, 60*1000);
|
||||
var timerDepartures = setInterval(getDepartures, 60*1000);
|
||||
|
||||
return function cleanup() {
|
||||
clearInterval(timer);
|
||||
clearInterval(timerTemperature);
|
||||
clearInterval(timerDepartures);
|
||||
}
|
||||
|
||||
}, []);
|
||||
|
||||
// rss feed to get articles from sokolov website
|
||||
const getRssFeed = () => {
|
||||
axios(SOKOLOV_RSS_URL).then(response => {
|
||||
const myJson = convertXML(response?.data);
|
||||
let data = myJson?.rss?.children[0]?.channel?.children;
|
||||
|
||||
if(!Array.isArray(data)) return;
|
||||
|
||||
// first 5 items are informational, so we skip them
|
||||
const result = data.slice(5).map(item => {
|
||||
const d = item?.item?.children;
|
||||
const url = d[1]?.link?.content.replace('amp;','');
|
||||
let pubDate = d[3]?.pubDate?.content;
|
||||
pubDate ? pubDate = new Date(pubDate) : pubDate = new Date();
|
||||
|
||||
return {title: d[0]?.title?.content, description: d[2]?.description?.content, link: url, pubDate: pubDate}
|
||||
})
|
||||
|
||||
console.log(result)
|
||||
setFeedData(result)
|
||||
}).catch(e => console.log(e))
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getRssFeed();
|
||||
var feed = setInterval(getRssFeed, 6*60*60*1000); //raz za 6 hodin
|
||||
return function cleanup() {
|
||||
clearInterval(feed);
|
||||
}
|
||||
},[])
|
||||
|
||||
const buildFeedView = () => {
|
||||
return feedData.map((item,index) => {
|
||||
return (
|
||||
<Box sx={{padding: 2}} key={index}>
|
||||
<Typography sx={{color: LOGO_COLOR}} variant="h6">{item.title}</Typography>
|
||||
<Typography variant='subtitle2' className='hoverOverLink' onClick={()=> setChosenArticle({clicked: true, url: item.link})}>Přečti celý článek ...</Typography>
|
||||
<Typography variant='body1'>{item.description}</Typography>
|
||||
<Typography sx={{color: FONT_COLOR}} variant='subtitle2'>{item.pubDate.toLocaleDateString('cs-Cz')}</Typography>
|
||||
</Box>)
|
||||
})
|
||||
|
||||
}
|
||||
sokolovFeed = buildFeedView();
|
||||
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className='containerTop'>
|
||||
<table key="dataTable" style={{width:'90%', color:'white', marginTop: '3vh'}} cellPadding="0" cellSpacing="0" align="center">
|
||||
<tbody>
|
||||
<tr style={{fontSize: MAIN_HEADER_FONT_SIZE}}>
|
||||
<td align="center">{date.toLocaleTimeString('sk-SK', OPTIONS)}</td>
|
||||
<td align="center">{dayOfWeek} {date.toLocaleDateString('sk-SK')}</td>
|
||||
<td align="center">{temperature} ℃</td>
|
||||
</tr>
|
||||
<tr style={{fontSize: MAIN_HEADER_FONT_SIZE}}>
|
||||
<td align="center" colSpan={3}>
|
||||
<hr></hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style={{fontSize: MAIN_HEADER_FONT_SIZE, verticalAlign: 'top', height: 70}}>
|
||||
<td align="center">LINKA</td>
|
||||
<td align="left">SMĚR</td>
|
||||
<td align="center">PŘÍJEZD</td>
|
||||
</tr>
|
||||
{
|
||||
departures.map(function(item, i){
|
||||
return <tr key={i} style={{fontSize: DATA_FONT_SIZE}}><td align="center">{item[0]}</td><td align="left">{item[2]}</td><td align="center">{item[1]}</td></tr>;
|
||||
})
|
||||
}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="center">
|
||||
<Button variant='contained' size="large" onClick={resetWeb}>Home</Button>
|
||||
</div>
|
||||
|
||||
<div key="containerBottom" className="containerBottom">
|
||||
{chosenArticle.clicked ? <iframe title="sokolovWeb" className="iframe" ref={iframeRef} onLoad={executeScroll} src={chosenArticle.url} ></iframe> :
|
||||
<Container className="scrollMarginTop" ref={containerRef} maxWidth={false}>
|
||||
<Paper elevation={2} sx={{margin:'1vh 10vw 1vh'}}>
|
||||
{sokolovFeed}
|
||||
</Paper>
|
||||
</Container>
|
||||
}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
|
||||
|
||||
const departures = [
|
||||
[ '6', '07:23', 'Sídl.Michal škola', [ 'X', '42' ] ],
|
||||
[ '3', '07:27', 'Sídliště Michal', [ 'X', '32' ] ],
|
||||
[ '2', '07:31', 'Sídliště Michal', [ 'X', '42' ] ],
|
||||
[ '3', '07:34', 'Závodu míru', [ 'X', '42' ] ],
|
||||
[ '4', '07:34', 'Závodu míru', [ 'X' ] ],
|
||||
[ '1', '07:35', 'Březová, aut. st.', [ 'X' ] ],
|
||||
[ '3', '07:45', 'Sídliště Michal', [ 'X' ] ],
|
||||
[ '33', '07:54', 'sídl.Michal škola', [ 'X', '42' ] ],
|
||||
[ '1', '07:55', 'Březová, aut. st.', [ 'X' ] ],
|
||||
[ '3', '07:58', 'Závodu míru', [ 'X', '42' ] ],
|
||||
[ '3', '08:10', 'Závodu míru', [ 'X', '32' ] ]
|
||||
]
|
||||
|
||||
// pubDate is date object
|
||||
const dummyData = [
|
||||
{
|
||||
title: "Silniceeee v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Nemocnice Sokolov získala akreditaci SAK",
|
||||
description:"Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10821",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.pravda.sk/",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10820",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate: 'Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)'
|
||||
}
|
||||
];
|
||||
|
||||
// const departures = [
|
||||
// [ '2', '3', '24.11.22 04:05', 'Závodu míru' ],
|
||||
// [ '290', '3', '24.11.22 04:25', 'Závodu míru' ],
|
||||
// [ '292', '3', '24.11.22 04:48', 'Závodu míru' ],
|
||||
// [ '296', '3', '24.11.22 04:58', 'Závodu míru' ],
|
||||
// [ '6', '3', '24.11.22 05:05', 'Závodu míru' ],
|
||||
// [ '300', '3', '24.11.22 05:18', 'Závodu míru' ],
|
||||
// [ '8', '3', '24.11.22 05:55', 'Závodu míru' ],
|
||||
// [ '16', '3', '24.11.22 06:30', 'Závodu míru' ],
|
||||
// [ '1', '33', '24.11.22 06:45', 'sídl. Michal škola' ],
|
||||
// [ '18', '3', '24.11.22 06:52', 'Hrušková' ],
|
||||
// [ '310', '3', '24.11.22 07:00', 'Závodu míru' ],
|
||||
// [ '22', '3', '24.11.22 07:10', 'Závodu míru' ],
|
||||
// [ '5', '33', '24.11.22 07:50', 'sídl. Michal škola' ],
|
||||
// [ '32', '3', '24.11.22 08:10', 'Závodu míru' ],
|
||||
// [ '7', '33', '24.11.22 08:25', 'sídl. Michal škola' ],
|
||||
// [ '100', '3', '24.11.22 08:30', 'Závodu míru' ],
|
||||
// [ '9', '33', '24.11.22 08:50', 'sídl. Michal škola' ],
|
||||
// [ '34', '3', '24.11.22 09:00', 'Závodu míru' ],
|
||||
// [ '38', '3', '24.11.22 09:20', 'Závodu míru' ],
|
||||
// [ '11', '33', '24.11.22 09:30', 'sídl. Michal škola' ],
|
||||
// [ '298', '3', '24.11.22 09:55', 'Závodu míru' ],
|
||||
// [ '2', '7', '24.11.22 10:10', 'Březová, aut. st.' ],
|
||||
// [ '13', '33', '24.11.22 10:20', 'sídl. Michal škola' ],
|
||||
// [ '48', '3', '24.11.22 10:50', 'Závodu míru' ],
|
||||
// [ '50', '3', '24.11.22 11:13', 'Závodu míru' ],
|
||||
// [ '15', '33', '24.11.22 11:25', 'sídl. Michal škola' ],
|
||||
// [ '52', '3', '24.11.22 11:40', 'Závodu míru' ],
|
||||
// [ '17', '33', '24.11.22 11:52', 'sídl. Michal škola' ],
|
||||
// [ '56', '3', '24.11.22 12:20', 'Závodu míru' ],
|
||||
// [ '62', '3', '24.11.22 12:40', 'Závodu míru' ],
|
||||
// [ '64', '3', '24.11.22 12:55', 'Závodu míru' ],
|
||||
// [ '19', '33', '24.11.22 13:00', 'sídl. Michal škola' ],
|
||||
// [ '66', '3', '24.11.22 13:20', 'Stará ovčárna' ],
|
||||
// [ '21', '33', '24.11.22 13:35', 'sídl. Michal škola' ],
|
||||
// [ '23', '33', '24.11.22 14:00', 'sídl. Michal škola' ],
|
||||
// [ '72', '3', '24.11.22 14:05', 'Závodu míru' ],
|
||||
// [ '25', '33', '24.11.22 14:42', 'sídl. Michal škola' ],
|
||||
// [ '94', '3', '24.11.22 14:48', 'Závodu míru' ],
|
||||
// [ '27', '33', '24.11.22 15:05', 'sídl. Michal škola' ],
|
||||
// [ '106', '3', '24.11.22 15:09', 'Závodu míru' ],
|
||||
// [ '84', '3', '24.11.22 15:35', 'Závodu míru' ],
|
||||
// [ '29', '33', '24.11.22 15:35', 'sídl. Michal škola' ],
|
||||
// [ '6', '7', '24.11.22 15:50', 'Březová, aut. st.' ],
|
||||
// [ '96', '3', '24.11.22 16:10', 'Závodu míru' ],
|
||||
// [ '31', '33', '24.11.22 16:10', 'sídl. Michal škola' ],
|
||||
// [ '4', '7', '24.11.22 16:25', 'Březová, aut. st.' ],
|
||||
// [ '102', '3', '24.11.22 16:30', 'Závodu míru' ],
|
||||
// [ '302', '3', '24.11.22 16:44', 'Závodu míru' ],
|
||||
// [ '8', '7', '24.11.22 16:55', 'Březová, aut. st.' ],
|
||||
// [ '108', '3', '24.11.22 17:05', 'Stará ovčárna' ],
|
||||
// [ '112', '3', '24.11.22 17:30', 'Závodu míru' ],
|
||||
// [ '114', '3', '24.11.22 17:53', 'Závodu míru' ],
|
||||
// [ '118', '3', '24.11.22 18:10', 'Závodu míru' ],
|
||||
// [ '120', '3', '24.11.22 18:30', 'Závodu míru' ],
|
||||
// [ '122', '3', '24.11.22 18:50', 'Závodu míru' ],
|
||||
// [ '124', '3', '24.11.22 19:15', 'Závodu míru' ],
|
||||
// [ '126', '3', '24.11.22 19:30', 'Závodu míru' ],
|
||||
// [ '130', '3', '24.11.22 19:50', 'Závodu míru' ],
|
||||
// [ '132', '3', '24.11.22 20:15', 'Závodu míru' ],
|
||||
// [ '134', '3', '24.11.22 20:45', 'Závodu míru' ],
|
||||
// [ '136', '3', '24.11.22 21:05', 'Závodu míru' ],
|
||||
// [ '256', '3', '24.11.22 21:20', 'Stará ovčárna' ],
|
||||
// [ '140', '3', '24.11.22 22:08', 'Stará ovčárna' ]
|
||||
// ];
|
||||
584
src/App.tsx
Normal file
584
src/App.tsx
Normal file
|
|
@ -0,0 +1,584 @@
|
|||
import React, { useState, useEffect, useRef } from "react";
|
||||
import axios from "axios";
|
||||
import { Box, Typography, Paper, Container, Button } from "@mui/material";
|
||||
import "./App.css";
|
||||
import { TChildren, TRssItem, TRssRawItem, TDepartures } from "./types";
|
||||
import { convertXML } from "simple-xml-to-json";
|
||||
|
||||
const MAIN_HEADER_FONT_SIZE = 50;
|
||||
const DATA_FONT_SIZE = 42;
|
||||
const TEMPERATURE_URL = "http://10.0.0.106:3000/gettemperature";
|
||||
const DEPARTURES_URL = "http://10.0.0.106:3000/getdepartures";
|
||||
const SOKOLOV_RSS_URL = "https://www.sokolov.cz/rss/";
|
||||
const DAYS_OF_WEEK = [
|
||||
"Neděle",
|
||||
"Pondělí",
|
||||
"Úterý",
|
||||
"Středa",
|
||||
"Čtvrtek",
|
||||
"Pátek",
|
||||
"Sobota",
|
||||
];
|
||||
const INACTIVITY_LIMIT = 300000;
|
||||
const OPTIONS = { hour12: false };
|
||||
// colors in sokolov website
|
||||
const LOGO_COLOR = "#82c55b"; // green
|
||||
const FONT_COLOR = "#00367b"; // blue
|
||||
|
||||
let msToMidnight: number;
|
||||
let updateDayOfWeek: ReturnType<typeof setInterval>;
|
||||
let sokolovFeed: React.JSX.Element[];
|
||||
|
||||
//function that runs, when user is not active, while article is loaded on screen
|
||||
function onInactive(ms: number, cb: () => void) {
|
||||
var wait = setTimeout(cb, ms);
|
||||
|
||||
window.onmousemove =
|
||||
window.onmousedown =
|
||||
window.onmousemove =
|
||||
window.ontouchstart =
|
||||
window.ontouchmove =
|
||||
window.ontouchend =
|
||||
window.onmouseup =
|
||||
window.onkeydown =
|
||||
window.onkeyup =
|
||||
window.onfocus =
|
||||
function () {
|
||||
clearTimeout(wait);
|
||||
wait = setTimeout(cb, ms);
|
||||
};
|
||||
}
|
||||
|
||||
function App() {
|
||||
var [date, setDate] = useState(new Date());
|
||||
var [temperature, setTemperature] = useState<string | number>("?");
|
||||
var [departures, setDepartures] = useState<TDepartures>([]);
|
||||
var [dayOfWeek, setDayOfWeek] = useState("");
|
||||
var [chosenArticle, setChosenArticle] = useState({ clicked: false, url: "" });
|
||||
var [feedData, setFeedData] = useState<TRssItem[]>([
|
||||
{
|
||||
title: "Chyba stažení dat, kontaktujte prosím administrátora",
|
||||
description: "",
|
||||
link: "",
|
||||
pubDate: new Date(),
|
||||
guid: "",
|
||||
},
|
||||
]);
|
||||
|
||||
// check, how long is user inactive, if reading an article. If more than 5 minutes, we load default screen
|
||||
function idle() {
|
||||
onInactive(INACTIVITY_LIMIT, function () {
|
||||
window.onmousemove =
|
||||
window.onmousedown =
|
||||
window.onmousemove =
|
||||
window.ontouchstart =
|
||||
window.ontouchmove =
|
||||
window.ontouchend =
|
||||
window.onmouseup =
|
||||
window.onkeydown =
|
||||
window.onkeyup =
|
||||
window.onfocus =
|
||||
null;
|
||||
setChosenArticle({ clicked: false, url: "" });
|
||||
});
|
||||
}
|
||||
|
||||
// to assure, that website in iframe loads at the top
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null);
|
||||
//to assure, that feed loads at the top
|
||||
const containerRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const executeScroll = () => {
|
||||
if (iframeRef.current) iframeRef.current.scrollIntoView(true);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (containerRef.current) {
|
||||
!chosenArticle.clicked &&
|
||||
containerRef.current.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
}, [chosenArticle]);
|
||||
|
||||
function updateDate() {
|
||||
setDate(new Date());
|
||||
}
|
||||
|
||||
// go back to rss feed page
|
||||
const resetWeb = () => {
|
||||
setChosenArticle({ clicked: false, url: "" });
|
||||
};
|
||||
|
||||
function getTemperature() {
|
||||
axios(TEMPERATURE_URL, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
let t = parseFloat(response.data);
|
||||
//console.log(t);
|
||||
if (isNaN(t)) return;
|
||||
|
||||
setTemperature(t);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function getDepartures() {
|
||||
axios(DEPARTURES_URL, {
|
||||
headers: {
|
||||
"Access-Control-Allow-Origin": "*",
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
const departures: TDepartures = response.data;
|
||||
setDepartures(departures);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.log(error);
|
||||
});
|
||||
}
|
||||
|
||||
function milisecondsToMidnight(): number {
|
||||
var d = new Date();
|
||||
var midnight = d.setHours(24, 0, 0, 0);
|
||||
var now = Date.now();
|
||||
var msToMidnight = midnight - now; //miliseconds to midnight
|
||||
return msToMidnight + 2000; // just to make sure day change after midnight, I am adding 2 seconds
|
||||
}
|
||||
|
||||
// we find out how long time is to midnight. after midnight is reached, getDay function is called and name of day is changed (streda --> ctvrtek).
|
||||
function getDay() {
|
||||
clearInterval(updateDayOfWeek);
|
||||
const date = new Date();
|
||||
setDayOfWeek(DAYS_OF_WEEK[date.getDay()]);
|
||||
|
||||
msToMidnight = milisecondsToMidnight();
|
||||
console.log("setDay called, ms to midnight", msToMidnight);
|
||||
updateDayOfWeek = setInterval(getDay, msToMidnight);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
updateDate();
|
||||
getTemperature();
|
||||
getDepartures();
|
||||
getDay();
|
||||
|
||||
var timer = setInterval(updateDate, 1000);
|
||||
var timerTemperature = setInterval(getTemperature, 60 * 1000);
|
||||
var timerDepartures = setInterval(getDepartures, 60 * 1000);
|
||||
|
||||
return function cleanup() {
|
||||
clearInterval(timer);
|
||||
clearInterval(timerTemperature);
|
||||
clearInterval(timerDepartures);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// rss feed to get articles from sokolov website
|
||||
const getRssFeed = () => {
|
||||
axios(SOKOLOV_RSS_URL)
|
||||
.then((response) => {
|
||||
const myJson = convertXML(response?.data);
|
||||
|
||||
console.log("--------", JSON.stringify(myJson));
|
||||
let data: TChildren = myJson?.rss?.children[0]?.channel?.children;
|
||||
|
||||
if (!Array.isArray(data)) return;
|
||||
|
||||
// first 5 items are informational, so we skip them
|
||||
const result: TRssItem[] = data.slice(5).map((item: TRssRawItem) => {
|
||||
const d = item?.item?.children;
|
||||
const url = d[1]?.link?.content.replace("amp;", "");
|
||||
let pubDate = d[3]?.pubDate?.content;
|
||||
pubDate ? (pubDate = new Date(pubDate)) : (pubDate = new Date());
|
||||
|
||||
return {
|
||||
title: d[0]?.title?.content,
|
||||
description: d[2]?.description?.content,
|
||||
link: url,
|
||||
pubDate: pubDate,
|
||||
guid: "",
|
||||
};
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
setFeedData(result);
|
||||
})
|
||||
.catch((e) => console.log(e));
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
getRssFeed();
|
||||
var feed = setInterval(getRssFeed, 6 * 60 * 60 * 1000); //raz za 6 hodin
|
||||
return function cleanup() {
|
||||
clearInterval(feed);
|
||||
};
|
||||
}, []);
|
||||
|
||||
const buildFeedView = (): React.JSX.Element[] => {
|
||||
if (
|
||||
feedData[0].title ===
|
||||
"Chyba stažení dat, kontaktujte prosím administrátora"
|
||||
) {
|
||||
return [
|
||||
<Box sx={{ padding: 2 }}>
|
||||
<Typography sx={{ color: LOGO_COLOR }} variant="h6">
|
||||
{feedData[0].title}
|
||||
</Typography>
|
||||
<Typography sx={{ color: FONT_COLOR }} variant="subtitle2">
|
||||
{feedData[0].pubDate.toLocaleDateString("cs-Cz")}
|
||||
</Typography>
|
||||
</Box>,
|
||||
];
|
||||
}
|
||||
|
||||
return feedData.map((item, index) => {
|
||||
return (
|
||||
<Box sx={{ padding: 2 }} key={index}>
|
||||
<Typography sx={{ color: LOGO_COLOR }} variant="h6">
|
||||
{item.title}
|
||||
</Typography>
|
||||
<Typography
|
||||
variant="subtitle2"
|
||||
className="hoverOverLink"
|
||||
onClick={() => {
|
||||
idle();
|
||||
setChosenArticle({ clicked: true, url: item.link });
|
||||
}}
|
||||
>
|
||||
Přečti celý článek ...
|
||||
</Typography>
|
||||
<Typography variant="body1">{item.description}</Typography>
|
||||
<Typography sx={{ color: FONT_COLOR }} variant="subtitle2">
|
||||
{item.pubDate.toLocaleDateString("cs-Cz")}
|
||||
</Typography>
|
||||
</Box>
|
||||
);
|
||||
});
|
||||
};
|
||||
sokolovFeed = buildFeedView();
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="containerTop">
|
||||
<table
|
||||
key="dataTable"
|
||||
style={{ width: "90%", color: "white", marginTop: "3vh" }}
|
||||
cellPadding="0"
|
||||
cellSpacing="0"
|
||||
align="center"
|
||||
>
|
||||
<tbody>
|
||||
<tr style={{ fontSize: MAIN_HEADER_FONT_SIZE }}>
|
||||
<td align="center">
|
||||
{date.toLocaleTimeString("sk-SK", OPTIONS)}
|
||||
</td>
|
||||
<td align="center">
|
||||
{dayOfWeek} {date.toLocaleDateString("sk-SK")}
|
||||
</td>
|
||||
<td align="center">{temperature} ℃</td>
|
||||
</tr>
|
||||
<tr style={{ fontSize: MAIN_HEADER_FONT_SIZE }}>
|
||||
<td align="center" colSpan={3}>
|
||||
<hr></hr>
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
style={{
|
||||
fontSize: MAIN_HEADER_FONT_SIZE,
|
||||
verticalAlign: "top",
|
||||
height: 70,
|
||||
}}
|
||||
>
|
||||
<td align="center">LINKA</td>
|
||||
<td align="left">SMĚR</td>
|
||||
<td align="center">PŘÍJEZD</td>
|
||||
</tr>
|
||||
{departures.map(function (item, i) {
|
||||
return (
|
||||
<tr key={i} style={{ fontSize: DATA_FONT_SIZE }}>
|
||||
<td align="center">{item[0]}</td>
|
||||
<td align="left">{item[2]}</td>
|
||||
<td align="center">{item[1]}</td>
|
||||
</tr>
|
||||
);
|
||||
})}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div className="center">
|
||||
<Button variant="contained" size="large" onClick={resetWeb}>
|
||||
Home
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div key="containerBottom" className="containerBottom">
|
||||
{chosenArticle.clicked ? (
|
||||
<iframe
|
||||
title="sokolovWeb"
|
||||
className="iframe"
|
||||
ref={iframeRef}
|
||||
onLoad={executeScroll}
|
||||
src={chosenArticle.url}
|
||||
></iframe>
|
||||
) : (
|
||||
<Container
|
||||
className="scrollMarginTop"
|
||||
ref={containerRef}
|
||||
maxWidth={false}
|
||||
>
|
||||
<Paper elevation={2} sx={{ margin: "1vh 10vw 1vh" }}>
|
||||
{sokolovFeed}
|
||||
</Paper>
|
||||
</Container>
|
||||
)}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default App;
|
||||
|
||||
const departures = [
|
||||
["6", "07:23", "Sídl.Michal škola", ["X", "42"]],
|
||||
["3", "07:27", "Sídliště Michal", ["X", "32"]],
|
||||
["2", "07:31", "Sídliště Michal", ["X", "42"]],
|
||||
["3", "07:34", "Závodu míru", ["X", "42"]],
|
||||
["4", "07:34", "Závodu míru", ["X"]],
|
||||
["1", "07:35", "Březová, aut. st.", ["X"]],
|
||||
["3", "07:45", "Sídliště Michal", ["X"]],
|
||||
["33", "07:54", "sídl.Michal škola", ["X", "42"]],
|
||||
["1", "07:55", "Březová, aut. st.", ["X"]],
|
||||
["3", "07:58", "Závodu míru", ["X", "42"]],
|
||||
["3", "08:10", "Závodu míru", ["X", "32"]],
|
||||
];
|
||||
|
||||
// pubDate is date object
|
||||
const dummyData = [
|
||||
{
|
||||
title: "Silniceeee v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Nemocnice Sokolov získala akreditaci SAK",
|
||||
description:
|
||||
"Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10821",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.pravda.sk/",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10820",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.Sokolov 10. dubna 2024 - Zdravotnický holding Penta Hospitals úspěšně pokračuje ve zvyšování kvality a bezpečnosti svých zdravotnických služeb. Po nemocnicích v Roudnici nad Labem, Vrchlabí, Ostrově nebo Písku nyní úspěšně prošla auditem Spojené akreditační komise (SAK) také Nemocnice Sokolov. Udělením akreditace SAK potvrdila, že v Sokolově je pacientům poskytována profesionální a bezpečná péče.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
{
|
||||
title: "Silnice v Hruškové se dočká opravy",
|
||||
description:
|
||||
"Silnice v Hruškové se brzy dočká částečné rekonstrukce. To ocení nejen obyvatelé této městské části ale také cyklisté, kteří tudy na jaře a v létě často projíždí.",
|
||||
link: "https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10822",
|
||||
pubDate:
|
||||
"Date Fri Apr 12 2024 10:03:45 GMT+0200 (Central European Summer Time)",
|
||||
},
|
||||
];
|
||||
|
||||
// const departures = [
|
||||
// [ '2', '3', '24.11.22 04:05', 'Závodu míru' ],
|
||||
// [ '290', '3', '24.11.22 04:25', 'Závodu míru' ],
|
||||
// [ '292', '3', '24.11.22 04:48', 'Závodu míru' ],
|
||||
// [ '296', '3', '24.11.22 04:58', 'Závodu míru' ],
|
||||
// [ '6', '3', '24.11.22 05:05', 'Závodu míru' ],
|
||||
// [ '300', '3', '24.11.22 05:18', 'Závodu míru' ],
|
||||
// [ '8', '3', '24.11.22 05:55', 'Závodu míru' ],
|
||||
// [ '16', '3', '24.11.22 06:30', 'Závodu míru' ],
|
||||
// [ '1', '33', '24.11.22 06:45', 'sídl. Michal škola' ],
|
||||
// [ '18', '3', '24.11.22 06:52', 'Hrušková' ],
|
||||
// [ '310', '3', '24.11.22 07:00', 'Závodu míru' ],
|
||||
// [ '22', '3', '24.11.22 07:10', 'Závodu míru' ],
|
||||
// [ '5', '33', '24.11.22 07:50', 'sídl. Michal škola' ],
|
||||
// [ '32', '3', '24.11.22 08:10', 'Závodu míru' ],
|
||||
// [ '7', '33', '24.11.22 08:25', 'sídl. Michal škola' ],
|
||||
// [ '100', '3', '24.11.22 08:30', 'Závodu míru' ],
|
||||
// [ '9', '33', '24.11.22 08:50', 'sídl. Michal škola' ],
|
||||
// [ '34', '3', '24.11.22 09:00', 'Závodu míru' ],
|
||||
// [ '38', '3', '24.11.22 09:20', 'Závodu míru' ],
|
||||
// [ '11', '33', '24.11.22 09:30', 'sídl. Michal škola' ],
|
||||
// [ '298', '3', '24.11.22 09:55', 'Závodu míru' ],
|
||||
// [ '2', '7', '24.11.22 10:10', 'Březová, aut. st.' ],
|
||||
// [ '13', '33', '24.11.22 10:20', 'sídl. Michal škola' ],
|
||||
// [ '48', '3', '24.11.22 10:50', 'Závodu míru' ],
|
||||
// [ '50', '3', '24.11.22 11:13', 'Závodu míru' ],
|
||||
// [ '15', '33', '24.11.22 11:25', 'sídl. Michal škola' ],
|
||||
// [ '52', '3', '24.11.22 11:40', 'Závodu míru' ],
|
||||
// [ '17', '33', '24.11.22 11:52', 'sídl. Michal škola' ],
|
||||
// [ '56', '3', '24.11.22 12:20', 'Závodu míru' ],
|
||||
// [ '62', '3', '24.11.22 12:40', 'Závodu míru' ],
|
||||
// [ '64', '3', '24.11.22 12:55', 'Závodu míru' ],
|
||||
// [ '19', '33', '24.11.22 13:00', 'sídl. Michal škola' ],
|
||||
// [ '66', '3', '24.11.22 13:20', 'Stará ovčárna' ],
|
||||
// [ '21', '33', '24.11.22 13:35', 'sídl. Michal škola' ],
|
||||
// [ '23', '33', '24.11.22 14:00', 'sídl. Michal škola' ],
|
||||
// [ '72', '3', '24.11.22 14:05', 'Závodu míru' ],
|
||||
// [ '25', '33', '24.11.22 14:42', 'sídl. Michal škola' ],
|
||||
// [ '94', '3', '24.11.22 14:48', 'Závodu míru' ],
|
||||
// [ '27', '33', '24.11.22 15:05', 'sídl. Michal škola' ],
|
||||
// [ '106', '3', '24.11.22 15:09', 'Závodu míru' ],
|
||||
// [ '84', '3', '24.11.22 15:35', 'Závodu míru' ],
|
||||
// [ '29', '33', '24.11.22 15:35', 'sídl. Michal škola' ],
|
||||
// [ '6', '7', '24.11.22 15:50', 'Březová, aut. st.' ],
|
||||
// [ '96', '3', '24.11.22 16:10', 'Závodu míru' ],
|
||||
// [ '31', '33', '24.11.22 16:10', 'sídl. Michal škola' ],
|
||||
// [ '4', '7', '24.11.22 16:25', 'Březová, aut. st.' ],
|
||||
// [ '102', '3', '24.11.22 16:30', 'Závodu míru' ],
|
||||
// [ '302', '3', '24.11.22 16:44', 'Závodu míru' ],
|
||||
// [ '8', '7', '24.11.22 16:55', 'Březová, aut. st.' ],
|
||||
// [ '108', '3', '24.11.22 17:05', 'Stará ovčárna' ],
|
||||
// [ '112', '3', '24.11.22 17:30', 'Závodu míru' ],
|
||||
// [ '114', '3', '24.11.22 17:53', 'Závodu míru' ],
|
||||
// [ '118', '3', '24.11.22 18:10', 'Závodu míru' ],
|
||||
// [ '120', '3', '24.11.22 18:30', 'Závodu míru' ],
|
||||
// [ '122', '3', '24.11.22 18:50', 'Závodu míru' ],
|
||||
// [ '124', '3', '24.11.22 19:15', 'Závodu míru' ],
|
||||
// [ '126', '3', '24.11.22 19:30', 'Závodu míru' ],
|
||||
// [ '130', '3', '24.11.22 19:50', 'Závodu míru' ],
|
||||
// [ '132', '3', '24.11.22 20:15', 'Závodu míru' ],
|
||||
// [ '134', '3', '24.11.22 20:45', 'Závodu míru' ],
|
||||
// [ '136', '3', '24.11.22 21:05', 'Závodu míru' ],
|
||||
// [ '256', '3', '24.11.22 21:20', 'Stará ovčárna' ],
|
||||
// [ '140', '3', '24.11.22 22:08', 'Stará ovčárna' ]
|
||||
// ];
|
||||
|
||||
// example of rss return data
|
||||
/*
|
||||
const a = {
|
||||
rss: {
|
||||
version: "2.0",
|
||||
children: [
|
||||
{
|
||||
channel: {
|
||||
children: [
|
||||
{
|
||||
title: {
|
||||
content: "Sokolov - aktuality",
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
content: "https://www.sokolov.cz/",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: {
|
||||
content: "Sokolov - aktuality",
|
||||
},
|
||||
},
|
||||
{
|
||||
ttl: {
|
||||
content: "60",
|
||||
},
|
||||
},
|
||||
{
|
||||
lastBuildDate: {
|
||||
content: "Sat, 27 Apr 2024 18:40:22 GMT",
|
||||
},
|
||||
},
|
||||
{
|
||||
item: {
|
||||
children: [
|
||||
{
|
||||
title: {
|
||||
content:
|
||||
"Biskup Tomáš Holub jednal na sokolovské radnici o rekonstrukci kostela na Starém náměstí",
|
||||
},
|
||||
},
|
||||
{
|
||||
link: {
|
||||
content:
|
||||
"https://www.sokolov.cz/vismo/dokumenty2.asp?id_org=15222&id=10868",
|
||||
},
|
||||
},
|
||||
{
|
||||
description: {
|
||||
content:
|
||||
"V rámci snahy sokolovské radnice o revitalizaci historického centra, jednal starosta Sokolova Petr Kubis s plzeňským biskupem Tomášem Holubem. Tématem schůzky byla rekonstrukce kostela svatého Jakuba Většího, který tvoří jednu z dominant Starého náměstí. Radnice už začala pracovat na obnově kapucínského kláštera. Jednat chce i se zástupci pravoslavné církve o renovaci nedaleké modlitebny. Oprava římskokatolického kostela by měla doplnit celkovou revitalizaci lokality. „Chtěli bychom, aby se Staré náměstí stalo odpočinkovým místem pro obyvatele Sokolova, ale i výchozím bodem pro návštěvníky. Vedle výsadby nových stromů zde připravujeme i instalaci laviček nebo interaktivních prvků, které by popisovaly historii města. Také chceme, aby zde začínaly naučné stezky, které plánujeme vytvořit,“ doplnil starosta Kubis.",
|
||||
},
|
||||
},
|
||||
{
|
||||
pubDate: {
|
||||
content: "Fri, 26 Apr 2024 16:31:48 GMT",
|
||||
},
|
||||
},
|
||||
{
|
||||
guid: {
|
||||
content: "dokumenty10868",
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
*/
|
||||
11
src/index.js
11
src/index.js
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css'
|
||||
import App from './App';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
13
src/index.tsx
Normal file
13
src/index.tsx
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import React from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import "./index.css";
|
||||
import App from "./App";
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById("root") as HTMLElement
|
||||
);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
48
src/types.d.ts
vendored
Normal file
48
src/types.d.ts
vendored
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// types, composed for axios Rss feed
|
||||
|
||||
export type TRssItem = {
|
||||
title: string;
|
||||
description: string;
|
||||
link: string;
|
||||
pubDate: Date;
|
||||
guid: string;
|
||||
};
|
||||
|
||||
export type TContent = { content: string };
|
||||
|
||||
export type TRssRawItem = {
|
||||
item: {
|
||||
children: [
|
||||
{ title: TContent },
|
||||
{ link: TContent },
|
||||
{ description: TContent },
|
||||
{ pubDate: { content: Date } },
|
||||
{ guid: TContent }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
export type TChildren = {
|
||||
children: [
|
||||
|{
|
||||
title: TContent;
|
||||
}
|
||||
| {
|
||||
link: TContent;
|
||||
}
|
||||
| {
|
||||
description: TContent;
|
||||
}
|
||||
| {
|
||||
ttl: TContent;
|
||||
}
|
||||
| {
|
||||
lastBuildDate: TContent;
|
||||
}
|
||||
| {
|
||||
item: RssRawItem;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
||||
export type TDepartures = array<string, string, string, string[]>[];
|
||||
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": [
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"esnext"
|
||||
],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx"
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
]
|
||||
}
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue