v1.1
This commit is contained in:
parent
3f30854c04
commit
295ed58901
5
.env
5
.env
@ -1 +1,4 @@
|
||||
VITE_API_BASE_URL=https://45.146.164.63:8080
|
||||
# VUE_APP_API_URL=http://31.129.106.67:8080
|
||||
# VUE_APP_GEO_URL=http://31.129.106.67:6001
|
||||
VUE_APP_API_URL=http://127.0.0.1:8080
|
||||
VUE_APP_GEO_URL=http://127.0.0.1:6001
|
@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<Main />
|
||||
<StopInfo />
|
||||
<CarrierInfo />
|
||||
<WeatherInfo />
|
||||
<CarrierInfo @president-appeal-toggle="presidentOpen = $event" />
|
||||
<WeatherInfo :is-president-address-open="presidentOpen" />
|
||||
<RouteInfo />
|
||||
</template>
|
||||
|
||||
@ -22,6 +22,11 @@ export default {
|
||||
WeatherInfo,
|
||||
RouteInfo,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
presidentOpen: false,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
@ -18,18 +18,29 @@ body {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.station-label-no-bg {
|
||||
.station-label-no-bg,
|
||||
.station-name-ru {
|
||||
background: transparent !important;
|
||||
border: none !important;
|
||||
box-shadow: none !important;
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
|
||||
/* max-width: 200px; */
|
||||
padding: 0 !important;
|
||||
/* text-wrap: revert; */
|
||||
}
|
||||
|
||||
.station-name-ru {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.station-name-en {
|
||||
font-size: 14px;
|
||||
color: #ffffffad;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.station-label-no-bg:before {
|
||||
display: none !important;
|
||||
}
|
||||
@ -40,6 +51,7 @@ body {
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.stopinfo .bg {
|
||||
@ -48,6 +60,15 @@ body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.stopinfo .bg * {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.stopinfo .container {
|
||||
margin-bottom: 75px !important;
|
||||
}
|
||||
|
||||
.container {
|
||||
@ -118,14 +139,22 @@ body {
|
||||
top: 18px;
|
||||
}
|
||||
|
||||
.landmarks-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.stoparticles {
|
||||
padding: 0 15px;
|
||||
height: 50px;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: auto;
|
||||
gap: 45px;
|
||||
text-align: center;
|
||||
gap: 15px;
|
||||
justify-content: space-around;
|
||||
background: rgb(187, 179, 170);
|
||||
background: linear-gradient(
|
||||
180deg,
|
||||
@ -150,6 +179,7 @@ body {
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
margin: 0 15px 15px 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.stop-buttons-container {
|
||||
@ -167,6 +197,7 @@ body {
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
margin-top: 15px;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.white {
|
||||
@ -225,6 +256,7 @@ body {
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 350px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.carrierinfo .bg {
|
||||
@ -310,7 +342,7 @@ body {
|
||||
.weatherinfo {
|
||||
z-index: 450;
|
||||
width: 225px;
|
||||
padding: 10px 15px;
|
||||
padding: 10px 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
@ -336,8 +368,9 @@ body {
|
||||
|
||||
.weatherinfo .date {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
padding: 2px 0 8px 0;
|
||||
font-size: 15px;
|
||||
font-weight: lighter;
|
||||
padding: 0 0 8px 0;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #ffffff7a;
|
||||
}
|
||||
@ -346,13 +379,16 @@ body {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
.current-weather {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
.current-weather div {
|
||||
text-align: center;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.temperature-celsius {
|
||||
font-size: 35px;
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
.forecast-day {
|
||||
@ -366,7 +402,7 @@ body {
|
||||
|
||||
.weather-forecast {
|
||||
width: 100%;
|
||||
padding: 0 10px;
|
||||
padding: 0;
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@ -376,15 +412,22 @@ body {
|
||||
.forecast {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 7px;
|
||||
gap: 10px;
|
||||
width: 90px;
|
||||
}
|
||||
|
||||
.forecast-day {
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
.additional-forecast {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-top: 1px solid #ffffff7a;
|
||||
padding: 10px 0 0 7px;
|
||||
padding: 10px 0 0 3px;
|
||||
gap: 7px;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.additional-forecast .humidity,
|
||||
@ -417,7 +460,7 @@ body {
|
||||
.route-names {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
/* gap: 2px; */
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
@ -478,7 +521,7 @@ body {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 310px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
background: rgba(0, 0, 0, 0);
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
@ -487,6 +530,7 @@ body {
|
||||
border-radius: 5px;
|
||||
z-index: 1001;
|
||||
transition: left 0.3s ease;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.carrierinfo .bg.hidden + .carrier-toggle {
|
||||
@ -550,21 +594,6 @@ body {
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.carrier-toggle {
|
||||
position: absolute;
|
||||
bottom: 10px;
|
||||
left: 310px;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border: none;
|
||||
color: #fff;
|
||||
font-size: 24px;
|
||||
cursor: pointer;
|
||||
padding: 5px 10px;
|
||||
border-radius: 5px;
|
||||
z-index: 1001;
|
||||
transition: left 0.3s ease;
|
||||
}
|
||||
|
||||
.carrierinfo .bg.hidden + .carrier-toggle {
|
||||
left: 10px;
|
||||
}
|
||||
@ -576,6 +605,7 @@ body {
|
||||
|
||||
.bg {
|
||||
transition: transform 0.3s ease;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.dropdown-name {
|
||||
@ -680,16 +710,6 @@ li.checked {
|
||||
|
||||
.stoparticle-option {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stoparticle-option.selected {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.stoparticle-option {
|
||||
cursor: pointer;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.stoparticle-option.selected {
|
||||
@ -958,3 +978,21 @@ li.checked {
|
||||
.sight-preview-wrapper {
|
||||
max-height: 300px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.governor-appeal {
|
||||
top: 140px;
|
||||
width: 440px;
|
||||
}
|
||||
|
||||
.governor-appeal p {
|
||||
max-height: 400px;
|
||||
line-height: 22px;
|
||||
}
|
||||
|
||||
.governor-appeal h3 {
|
||||
font-size: 22px;
|
||||
}
|
||||
|
@ -589,7 +589,6 @@
|
||||
clip-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
|
||||
<span class="gos-name"
|
||||
>При поддержке Правительства <br />
|
||||
Санкт-Петербурга</span
|
||||
@ -713,7 +712,7 @@
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div v-if="showGovernorAppeal" class="sight-preview-panel">
|
||||
<div v-if="showGovernorAppeal" class="governor-appeal sight-preview-panel">
|
||||
<img :src="governorAppealImage" v-if="governorAppealImage" />
|
||||
<h3>{{ governorAppealTitle }}</h3>
|
||||
<p>{{ governorAppealText }}</p>
|
||||
@ -739,16 +738,17 @@
|
||||
|
||||
<script>
|
||||
import "../assets/style/main.css";
|
||||
import { API_URL, GEO_URL } from "../config";
|
||||
|
||||
export default {
|
||||
name: "StopInfo",
|
||||
name: "CarrierInfo",
|
||||
data() {
|
||||
return {
|
||||
stations: [],
|
||||
showList: false,
|
||||
sights: [],
|
||||
showSightsList: false,
|
||||
routeId: null,
|
||||
routeId: 1,
|
||||
isHidden: true,
|
||||
selectedSightId: null,
|
||||
selectedSightName: "",
|
||||
@ -763,6 +763,7 @@ export default {
|
||||
governorAppealId: null,
|
||||
selectedSightWatermarkLU: "",
|
||||
selectedSightWatermarkRD: "",
|
||||
inactivityTimer: null,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
@ -778,16 +779,10 @@ export default {
|
||||
},
|
||||
async fetchStops() {
|
||||
try {
|
||||
const geoResponse = await fetch(
|
||||
"http://31.129.106.67:6001/v1/geolocation/context"
|
||||
);
|
||||
const geoResponse = await fetch(`${GEO_URL}/v1/geolocation/context`);
|
||||
const geoData = await geoResponse.json();
|
||||
const token = this.getCookie("auth_token");
|
||||
const routeDetailsRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/route/${geoData.routeId}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/route/${geoData.routeId}`
|
||||
);
|
||||
const routeDetails = await routeDetailsRes.json();
|
||||
const appealId = routeDetails.governor_appeal;
|
||||
@ -802,29 +797,18 @@ export default {
|
||||
|
||||
if (appealId && appealId !== 0) {
|
||||
try {
|
||||
const articleRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/article/${appealId}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const articleRes = await fetch(`${API_URL}/article/${appealId}`);
|
||||
const articleData = await articleRes.json();
|
||||
this.governorAppealTitle = articleData.heading;
|
||||
this.governorAppealText = articleData.body;
|
||||
|
||||
const mediaRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/article/${appealId}/media`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/article/${appealId}/media`
|
||||
);
|
||||
const mediaData = await mediaRes.json();
|
||||
if (mediaData.length) {
|
||||
const imageRes = await fetch(
|
||||
`http://31.129.106.67:8080/media/${mediaData[0].id}/download`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/media/${mediaData[0].id}/download`
|
||||
);
|
||||
this.governorAppealImage = await imageRes.url;
|
||||
} else {
|
||||
@ -846,10 +830,7 @@ export default {
|
||||
if (!this.routeId) throw new Error("Route number not found");
|
||||
|
||||
const stopsResponse = await fetch(
|
||||
`https://wn-ts.krbl.ru/route/${this.routeId}/station`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/route/${this.routeId}/station`
|
||||
);
|
||||
const stopsData = await stopsResponse.json();
|
||||
this.stations = stopsData;
|
||||
@ -859,22 +840,11 @@ export default {
|
||||
},
|
||||
async fetchSights() {
|
||||
try {
|
||||
const token = this.getCookie("auth_token");
|
||||
const response = await fetch(
|
||||
`https://wn-ts.krbl.ru/route/${this.routeId}/sight`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const response = await fetch(`${API_URL}/route/${this.routeId}/sight`);
|
||||
const rawSights = await response.json();
|
||||
const detailedSights = await Promise.all(
|
||||
rawSights.map(async (sight) => {
|
||||
const detailRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/sight/${sight.id}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const detailRes = await fetch(`${API_URL}/sight/${sight.id}`);
|
||||
const detail = await detailRes.json();
|
||||
return { id: sight.id, name: detail.name };
|
||||
})
|
||||
@ -886,6 +856,8 @@ export default {
|
||||
},
|
||||
async toggleSights() {
|
||||
this.showGovernorAppeal = false;
|
||||
this.$emit("president-appeal-toggle", this.showGovernorAppeal);
|
||||
|
||||
if (!this.sights.length) {
|
||||
await this.fetchSights();
|
||||
}
|
||||
@ -899,45 +871,29 @@ export default {
|
||||
},
|
||||
async selectSight(sightId) {
|
||||
this.selectedSightId = sightId;
|
||||
const token = this.getCookie("auth_token");
|
||||
try {
|
||||
const sightRes = await fetch(`https://wn-ts.krbl.ru/sight/${sightId}`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
const sightRes = await fetch(`${API_URL}/sight/${sightId}`);
|
||||
const sightData = await sightRes.json();
|
||||
this.selectedSightName = sightData.name;
|
||||
|
||||
const articleId = sightData.left_article;
|
||||
|
||||
const articleRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/article/${articleId}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const articleRes = await fetch(`${API_URL}/article/${articleId}`);
|
||||
const articleData = await articleRes.json();
|
||||
this.selectedSightText = articleData.body;
|
||||
|
||||
const mediaRes = await fetch(
|
||||
`https://wn-ts.krbl.ru/article/${articleId}/media`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const mediaRes = await fetch(`${API_URL}/article/${articleId}/media`);
|
||||
const mediaData = await mediaRes.json();
|
||||
if (mediaData.length) {
|
||||
const imageRes = await fetch(
|
||||
`http://31.129.106.67:8080/media/${mediaData[0].id}/download`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/media/${mediaData[0].id}/download`
|
||||
);
|
||||
this.selectedSightImage = await imageRes.url;
|
||||
this.selectedSightWatermarkLU = sightData.watermark_lu
|
||||
? `http://31.129.106.67:8080/media/${sightData.watermark_lu}/download`
|
||||
? `${API_URL}/media/${sightData.watermark_lu}/download`
|
||||
: "";
|
||||
this.selectedSightWatermarkRD = sightData.watermark_rd
|
||||
? `http://31.129.106.67:8080/media/${sightData.watermark_rd}/download`
|
||||
? `${API_URL}/media/${sightData.watermark_rd}/download`
|
||||
: "";
|
||||
} else {
|
||||
this.selectedSightImage = "";
|
||||
@ -950,6 +906,8 @@ export default {
|
||||
},
|
||||
async toggleList() {
|
||||
this.showGovernorAppeal = false;
|
||||
this.$emit("president-appeal-toggle", this.showGovernorAppeal);
|
||||
|
||||
if (!this.stations.length) {
|
||||
await this.fetchStops();
|
||||
}
|
||||
@ -961,6 +919,7 @@ export default {
|
||||
this.showSightsList = false;
|
||||
this.showSightPreview = false;
|
||||
this.showGovernorAppeal = false;
|
||||
this.$emit("president-appeal-toggle", this.showGovernorAppeal);
|
||||
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty(
|
||||
@ -980,6 +939,7 @@ export default {
|
||||
weatherInfo?.classList.remove("shifted-left");
|
||||
}
|
||||
});
|
||||
this.resetInactivityTimer();
|
||||
},
|
||||
handleClickOutside() {
|
||||
// пупупу
|
||||
@ -988,10 +948,28 @@ export default {
|
||||
console.log("Кнопка обращения губернатора нажата");
|
||||
this.showGovernorAppeal = !this.showGovernorAppeal;
|
||||
this.showSightPreview = false;
|
||||
|
||||
this.$emit("president-appeal-toggle", this.showGovernorAppeal);
|
||||
},
|
||||
resetInactivityTimer() {
|
||||
clearTimeout(this.inactivityTimer);
|
||||
this.inactivityTimer = setTimeout(this.hidePanelIfActive, 300000); // 5m
|
||||
},
|
||||
hidePanelIfActive() {
|
||||
if (!this.isHidden) {
|
||||
this.toggleCarrierInfo();
|
||||
}
|
||||
},
|
||||
handleUserActivity() {
|
||||
this.resetInactivityTimer();
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
document.addEventListener("click", this.handleClickOutside);
|
||||
["mousemove", "touchstart", "keydown", "click"].forEach((evt) =>
|
||||
document.addEventListener(evt, this.handleUserActivity)
|
||||
);
|
||||
this.resetInactivityTimer();
|
||||
const root = document.documentElement;
|
||||
root.style.setProperty("--panel-offset", "20px");
|
||||
const routeInfo = document.querySelector(".routeinfo");
|
||||
@ -1003,6 +981,10 @@ export default {
|
||||
console.log("hasGovernorAppeal в mounted:", this.hasGovernorAppeal);
|
||||
},
|
||||
beforeUnmount() {
|
||||
["mousemove", "touchstart", "keydown", "click"].forEach((evt) =>
|
||||
document.removeEventListener(evt, this.handleUserActivity)
|
||||
);
|
||||
clearTimeout(this.inactivityTimer);
|
||||
document.removeEventListener("click", this.handleClickOutside);
|
||||
},
|
||||
};
|
||||
|
File diff suppressed because one or more lines are too long
@ -2,20 +2,64 @@
|
||||
<div class="routeinfo">
|
||||
<div class="route-number">{{ routeNumber }}</div>
|
||||
<div class="route-names">
|
||||
<div class="route-name" v-if="startStopName && endStopName">
|
||||
<!-- Russian names -->
|
||||
<div class="route-name ru">
|
||||
<div class="scroll-wrapper">
|
||||
<div class="scroll-inner">
|
||||
<div :class="isStartScrolling ? 'scroll-inner scrolling' : ''">
|
||||
<div class="scroll-content">
|
||||
<div class="name-block">
|
||||
<span class="name">
|
||||
{{ startStopName }} — {{ endStopName }}
|
||||
{{ startStopName }} — {{ endStopName }}
|
||||
{{ startStopName }} — {{ endStopName }}
|
||||
<span class="name" ref="startStopRuText">
|
||||
<template v-if="isStartScrolling">
|
||||
{{ startStopName }}
|
||||
{{ startStopName }} {{ startStopName }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ startStopName }}
|
||||
</template>
|
||||
</span>
|
||||
<span class="translate">
|
||||
{{ startStopNameEn }} — {{ endStopNameEn }}
|
||||
{{ startStopNameEn }} — {{ endStopNameEn }}
|
||||
{{ startStopNameEn }} — {{ endStopNameEn }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="route-name ru">
|
||||
<div class="scroll-wrapper">
|
||||
<div :class="isEndScrolling ? 'scroll-inner scrolling' : ''">
|
||||
<div class="scroll-content">
|
||||
<div class="name-block">
|
||||
<span class="name" ref="endStopRuText">
|
||||
<template v-if="isEndScrolling">
|
||||
{{ endStopName }}
|
||||
{{ endStopName }} {{ endStopName }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ endStopName }}
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- English names -->
|
||||
<div class="route-name en">
|
||||
<div class="scroll-wrapper">
|
||||
<div :class="isEnScrolling ? 'scroll-inner scrolling' : ''">
|
||||
<div class="scroll-content">
|
||||
<div class="name-block">
|
||||
<span class="translate" ref="enText">
|
||||
<template v-if="isEnScrolling">
|
||||
{{ startStopNameEn }} —
|
||||
{{ endStopNameEn }}
|
||||
{{ startStopNameEn }} —
|
||||
{{ endStopNameEn }}
|
||||
{{ startStopNameEn }} — {{ endStopNameEn }}
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ startStopNameEn }} — {{ endStopNameEn }}
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -27,47 +71,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
async function requestAuth() {
|
||||
const response = await fetch("https://wn-ts.krbl.ru/auth/login", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
email: "admin",
|
||||
password: "changeme",
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
Cookies.set("auth_token", data.token);
|
||||
return data.token;
|
||||
}
|
||||
|
||||
async function checkAuth() {
|
||||
const token = Cookies.get("auth_token");
|
||||
try {
|
||||
if (!token) {
|
||||
return await requestAuth();
|
||||
} else {
|
||||
const response = await fetch("https://wn-ts.krbl.ru/auth/me", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
|
||||
if (response.status === 401) {
|
||||
return await requestAuth();
|
||||
}
|
||||
}
|
||||
return token;
|
||||
} catch (error) {
|
||||
console.error("Auth check failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
import { API_URL, GEO_URL } from "../config";
|
||||
|
||||
export default {
|
||||
name: "RouteInfo",
|
||||
@ -78,37 +82,36 @@ export default {
|
||||
endStopName: "",
|
||||
startStopNameEn: "",
|
||||
endStopNameEn: "",
|
||||
isStartScrolling: false,
|
||||
isEndScrolling: false,
|
||||
isEnScrolling: false,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
startStopName() {
|
||||
this.$nextTick(this.checkScroll);
|
||||
},
|
||||
endStopName() {
|
||||
this.$nextTick(this.checkScroll);
|
||||
},
|
||||
startStopNameEn() {
|
||||
this.$nextTick(this.checkScroll);
|
||||
},
|
||||
endStopNameEn() {
|
||||
this.$nextTick(this.checkScroll);
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
const contextRes = await fetch(
|
||||
"http://31.129.106.67:6001/v1/geolocation/context"
|
||||
);
|
||||
const contextRes = await fetch(`${GEO_URL}/v1/geolocation/context`);
|
||||
const data = await contextRes.json();
|
||||
this.routeNumber = data.routeNumber;
|
||||
|
||||
const startStopId = data.startStopId;
|
||||
const endStopId = data.endStopId;
|
||||
|
||||
const token = await checkAuth();
|
||||
if (!token) {
|
||||
console.error(
|
||||
"No valid token received, skipping wn-ts.krbl.ru requests."
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const [startStopRes, endStopRes] = await Promise.all([
|
||||
fetch(`https://wn-ts.krbl.ru/station/${startStopId}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}),
|
||||
fetch(`https://wn-ts.krbl.ru/station/${endStopId}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}),
|
||||
fetch(`${API_URL}/station/${startStopId}`),
|
||||
fetch(`${API_URL}/station/${endStopId}`),
|
||||
]);
|
||||
|
||||
const startStopData = await startStopRes.json();
|
||||
@ -118,16 +121,8 @@ export default {
|
||||
this.endStopName = endStopData.name;
|
||||
|
||||
const [startStopEnRes, endStopEnRes] = await Promise.all([
|
||||
fetch(`https://wn-ts.krbl.ru/station/${startStopId}?lang=en`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}),
|
||||
fetch(`https://wn-ts.krbl.ru/station/${endStopId}?lang=en`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}),
|
||||
fetch(`${API_URL}/station/${startStopId}?lang=en`),
|
||||
fetch(`${API_URL}/station/${endStopId}?lang=en`),
|
||||
]);
|
||||
|
||||
const startStopEnData = await startStopEnRes.json();
|
||||
@ -135,7 +130,45 @@ export default {
|
||||
|
||||
this.startStopNameEn = startStopEnData.name;
|
||||
this.endStopNameEn = endStopEnData.name;
|
||||
|
||||
this.$nextTick(() => {
|
||||
this.checkScroll();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
checkScroll() {
|
||||
const threshold = 280;
|
||||
if (this.$refs.startStopRuText) {
|
||||
this.isStartScrolling =
|
||||
this.$refs.startStopRuText.offsetWidth > threshold;
|
||||
}
|
||||
if (this.$refs.endStopRuText) {
|
||||
this.isEndScrolling = this.$refs.endStopRuText.offsetWidth > threshold;
|
||||
}
|
||||
if (this.$refs.enText) {
|
||||
this.isEnScrolling = this.$refs.enText.offsetWidth > threshold;
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.route-name {
|
||||
overflow: hidden;
|
||||
width: 280px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.scroll-inner.scrolling {
|
||||
animation: marquee 12s linear infinite;
|
||||
}
|
||||
|
||||
@keyframes marquee {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -98,7 +98,7 @@
|
||||
</div>
|
||||
</transition>
|
||||
<transition name="expand-collapse-transition">
|
||||
<div>
|
||||
<div class="landmarks-container">
|
||||
<div class="landmarks" @click="toggleSightsList">
|
||||
<div class="landmarks-header">
|
||||
<svg
|
||||
@ -149,10 +149,7 @@
|
||||
:key="sight.id"
|
||||
class="sight-card"
|
||||
>
|
||||
<img
|
||||
class="sight-thumbnail"
|
||||
:src="`http://31.129.106.67:8080/media/${sight.thumbnail}/download`"
|
||||
/>
|
||||
<img class="sight-thumbnail" :src="sight.thumbnailUrl" />
|
||||
<div class="sight-title">{{ sight.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -167,8 +164,9 @@
|
||||
|
||||
<script>
|
||||
import "../assets/style/main.css";
|
||||
import { API_URL, GEO_URL } from "../config";
|
||||
|
||||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
|
||||
export default {
|
||||
name: "StopInfo",
|
||||
@ -176,6 +174,8 @@ export default {
|
||||
return {
|
||||
isModalOpen: false,
|
||||
autoCloseTimer: null,
|
||||
articleInactivityTimer: null,
|
||||
sightsInactivityTimer: null,
|
||||
imageUrl: "",
|
||||
defaultImageUrl:
|
||||
"https://lh3.googleusercontent.com/gps-cs-s/AB5caB8lUwofb2NIg6n0-cEl8nIWsySAUc52KNj4XezuOdo-aeqTgQlD1kTVa5MaynL2Yg4ByoTYTKNTR7K59f7kjzU9yzpudstjRiT2F6M_ilxFYFpcvMZz6OwlRFF2MrsCPSwUa7vqew=s680-w680-h510",
|
||||
@ -246,41 +246,6 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async checkAuth() {
|
||||
let token = Cookies.get("auth_token");
|
||||
if (!token) {
|
||||
await this.requestAuth();
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await axios.get("https://wn-ts.krbl.ru/auth/me", {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
await this.requestAuth();
|
||||
}
|
||||
},
|
||||
async requestAuth() {
|
||||
const response = await axios.post("https://wn-ts.krbl.ru/auth/login", {
|
||||
email: "admin",
|
||||
password: "changeme",
|
||||
});
|
||||
const token = response.data.token;
|
||||
Cookies.set("auth_token", token);
|
||||
document.cookie = `auth_token=${token}; path=/;`;
|
||||
},
|
||||
getCookie(name) {
|
||||
const matches = document.cookie.match(
|
||||
new RegExp(
|
||||
"(?:^|; )" +
|
||||
name.replace(/([.$?*|{}()[\]\\/+^])/g, "\\$1") +
|
||||
"=([^;]*)"
|
||||
)
|
||||
);
|
||||
return matches ? decodeURIComponent(matches[1]) : undefined;
|
||||
},
|
||||
openModal() {
|
||||
const imageDiv = this.$el.querySelector(".img");
|
||||
if (imageDiv) {
|
||||
@ -301,74 +266,59 @@ export default {
|
||||
},
|
||||
async fetchSightInfo() {
|
||||
if (!this.sightId) {
|
||||
console.warn("No sightId provided for fetchSightInfo");
|
||||
console.log("No sightId provided for fetchSightInfo");
|
||||
return;
|
||||
}
|
||||
const token = this.getCookie("auth_token");
|
||||
const response = await axios.get(
|
||||
`https://wn-ts.krbl.ru/sight/${this.sightId}`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
);
|
||||
const response = await axios.get(`${API_URL}/sight/${this.sightId}`);
|
||||
this.stopName = response.data.name;
|
||||
this.watermarkLU = response.data.watermark_lu
|
||||
? `http://31.129.106.67:8080/media/${response.data.watermark_lu}/download`
|
||||
: "";
|
||||
this.watermarkRD = response.data.watermark_rd
|
||||
? `http://31.129.106.67:8080/media/${response.data.watermark_rd}/download`
|
||||
: "";
|
||||
if (response.data.watermark_lu) {
|
||||
this.watermarkLU = await this.getMediaBlobUrl(
|
||||
response.data.watermark_lu
|
||||
);
|
||||
} else {
|
||||
this.watermarkLU = "";
|
||||
}
|
||||
if (response.data.watermark_rd) {
|
||||
this.watermarkRD = await this.getMediaBlobUrl(
|
||||
response.data.watermark_rd
|
||||
);
|
||||
} else {
|
||||
this.watermarkRD = "";
|
||||
}
|
||||
},
|
||||
async fetchArticles() {
|
||||
if (!this.sightId) {
|
||||
console.warn("No sightId provided for fetchArticles");
|
||||
return;
|
||||
}
|
||||
const token = this.getCookie("auth_token");
|
||||
const response = await axios.get(
|
||||
`https://wn-ts.krbl.ru/sight/${this.sightId}/article`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
`${API_URL}/sight/${this.sightId}/article`
|
||||
);
|
||||
this.articles = response.data;
|
||||
if (this.articles.length > 0) {
|
||||
this.selectArticle(this.articles[0].id);
|
||||
this.resetArticleInactivityTimer();
|
||||
}
|
||||
},
|
||||
async fetchSights() {
|
||||
const token = this.getCookie("auth_token");
|
||||
const geoRes = await axios.get(
|
||||
"http://31.129.106.67:6001/v1/geolocation/context"
|
||||
);
|
||||
const geoRes = await axios.get(`${GEO_URL}/v1/geolocation/context`);
|
||||
const routeId = geoRes.data.routeId;
|
||||
if (!routeId) {
|
||||
console.warn("Missing routeId in geo context:", geoRes.data);
|
||||
return;
|
||||
}
|
||||
const sightsRes = await axios.get(
|
||||
`https://wn-ts.krbl.ru/route/${routeId}/sight`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const sightsRes = await axios.get(`${API_URL}/route/${routeId}/sight`);
|
||||
const rawSights = sightsRes.data;
|
||||
const detailedSights = await Promise.all(
|
||||
rawSights.map(async (sight) => {
|
||||
const detailRes = await axios.get(
|
||||
`https://wn-ts.krbl.ru/sight/${sight.id}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const detailRes = await axios.get(`${API_URL}/sight/${sight.id}`);
|
||||
const thumbnailUrl = detailRes.data.thumbnail
|
||||
? await this.getMediaBlobUrl(detailRes.data.thumbnail)
|
||||
: "";
|
||||
return {
|
||||
id: sight.id,
|
||||
name: detailRes.data.name,
|
||||
thumbnail: detailRes.data.thumbnail,
|
||||
thumbnailUrl,
|
||||
};
|
||||
})
|
||||
);
|
||||
@ -376,27 +326,63 @@ export default {
|
||||
},
|
||||
toggleSightsList() {
|
||||
this.showSightsList = !this.showSightsList;
|
||||
if (this.showSightsList) {
|
||||
this.resetSightsInactivityTimer();
|
||||
} else if (this.sightsInactivityTimer) {
|
||||
clearTimeout(this.sightsInactivityTimer);
|
||||
this.sightsInactivityTimer = null;
|
||||
}
|
||||
},
|
||||
resetSightsInactivityTimer() {
|
||||
if (this.articleInactivityTimer) {
|
||||
clearTimeout(this.articleInactivityTimer);
|
||||
}
|
||||
if (this.sightsInactivityTimer) {
|
||||
clearTimeout(this.sightsInactivityTimer);
|
||||
}
|
||||
if (this.showSightsList) {
|
||||
this.sightsInactivityTimer = setTimeout(() => {
|
||||
this.showSightsList = false;
|
||||
this.sightsInactivityTimer = null;
|
||||
}, 300000); // 5 m
|
||||
}
|
||||
},
|
||||
resetArticleInactivityTimer() {
|
||||
if (this.articleInactivityTimer)
|
||||
clearTimeout(this.articleInactivityTimer);
|
||||
|
||||
this.articleInactivityTimer = setTimeout(() => {
|
||||
if (
|
||||
this.articles.length > 0 &&
|
||||
this.selectedArticleId !== this.articles[0].id
|
||||
) {
|
||||
this.selectArticle(this.articles[0].id);
|
||||
}
|
||||
}, 300_000); // 5 m
|
||||
},
|
||||
handleUserActivity() {
|
||||
if (this.showSightsList) this.resetSightsInactivityTimer();
|
||||
this.resetArticleInactivityTimer();
|
||||
},
|
||||
selectArticle(id) {
|
||||
this.resetArticleInactivityTimer();
|
||||
this.selectedArticleId = id;
|
||||
const selected = this.articles.find((article) => article.id === id);
|
||||
this.selectedArticleBody = selected ? selected.body : "";
|
||||
this.fetchArticleMedia(id);
|
||||
},
|
||||
async fetchArticleMedia(articleId) {
|
||||
const token = this.getCookie("auth_token");
|
||||
try {
|
||||
const response = await axios.get(
|
||||
`https://wn-ts.krbl.ru/article/${articleId}/media`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
}
|
||||
`${API_URL}/article/${articleId}/media`
|
||||
);
|
||||
if (response.data && response.data.length > 0) {
|
||||
const mediaId = response.data[0].id;
|
||||
this.imageUrl = `http://31.129.106.67:8080/media/${mediaId}/download`;
|
||||
try {
|
||||
this.imageUrl = await this.getMediaBlobUrl(mediaId);
|
||||
} catch {
|
||||
this.imageUrl = `${API_URL}/media/${mediaId}/download`;
|
||||
}
|
||||
} else {
|
||||
this.imageUrl = "";
|
||||
}
|
||||
@ -405,39 +391,60 @@ export default {
|
||||
this.imageUrl = "";
|
||||
}
|
||||
},
|
||||
async fetchGeolocationContext() {
|
||||
|
||||
async getMediaBlobUrl(mediaId) {
|
||||
try {
|
||||
const response = await axios.get(
|
||||
"http://31.129.106.67:6001/v1/geolocation/context"
|
||||
);
|
||||
this.routeProgress = response.data.routeProgress;
|
||||
console.log("Updated routeProgress:", this.routeProgress);
|
||||
const token = this.getCookie("auth_token");
|
||||
const stopsResponse = await axios.get(
|
||||
`https://wn-ts.krbl.ru/route/${response.data.routeId}/station`,
|
||||
`${API_URL}/media/${mediaId}/download`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
responseType: "blob",
|
||||
}
|
||||
);
|
||||
return URL.createObjectURL(response.data);
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`Failed to download media ${mediaId}:`,
|
||||
error?.response?.status,
|
||||
error?.response?.data || error.message
|
||||
);
|
||||
return `${API_URL}/media/${mediaId}/download`;
|
||||
}
|
||||
},
|
||||
async fetchGeolocationContext() {
|
||||
try {
|
||||
const response = await axios.get(`${GEO_URL}/v1/geolocation/context`);
|
||||
this.routeProgress = response.data.routeProgress;
|
||||
const stopsResponse = await axios.get(
|
||||
`${API_URL}/route/${response.data.routeId}/station`
|
||||
);
|
||||
this.stops = stopsResponse.data;
|
||||
const newSightId = response.data.nearestSightId;
|
||||
let newSightId = response.data.nearestSightId;
|
||||
|
||||
if (!newSightId) {
|
||||
if (!this.sights || this.sights.length === 0) {
|
||||
await this.fetchSights();
|
||||
}
|
||||
if (this.sights && this.sights.length > 0) {
|
||||
newSightId = this.sights[1].id;
|
||||
}
|
||||
}
|
||||
if (newSightId && newSightId !== this.sightId) {
|
||||
this.sightId = newSightId;
|
||||
await this.fetchSightInfo();
|
||||
await this.fetchArticles();
|
||||
}
|
||||
const nextStopId = response.data.routeProgress?.endStopId;
|
||||
console.log("Fetched next stop ID:", nextStopId);
|
||||
console.log("Stops:", this.stops);
|
||||
// console.log("Fetched next stop ID:", nextStopId);
|
||||
// console.log("Stops:", this.stops);
|
||||
if (nextStopId && this.stops) {
|
||||
const nextStop = this.stops.find((stop) => stop.id == nextStopId);
|
||||
console.log("Fetched next stop ID:", nextStopId);
|
||||
console.log("Matching stop:", nextStop);
|
||||
// console.log("Fetched next stop ID:", nextStopId);
|
||||
// console.log("Matching stop:", nextStop);
|
||||
if (nextStop && nextStop.transfers) {
|
||||
console.log("Transfers at next stop:", nextStop.transfers);
|
||||
// console.log("Transfers at next stop:", nextStop.transfers);
|
||||
this.nextStopTransfers = nextStop.transfers;
|
||||
} else {
|
||||
console.log("No transfers found at next stop");
|
||||
// console.log("No transfers found at next stop");
|
||||
this.nextStopTransfers = null;
|
||||
}
|
||||
}
|
||||
@ -456,7 +463,7 @@ export default {
|
||||
toggleTransfers() {
|
||||
console.log("Transfer toggle clicked");
|
||||
this.showTransfers = !this.showTransfers;
|
||||
console.log("showTransfers:", this.showTransfers);
|
||||
// console.log("showTransfers:", this.showTransfers);
|
||||
|
||||
if (!this.showTransfers) {
|
||||
return;
|
||||
@ -468,32 +475,46 @@ export default {
|
||||
}
|
||||
|
||||
const nextStopId = this.routeProgress.endStopId;
|
||||
console.log("Next stop ID from routeProgress:", nextStopId);
|
||||
console.log("All stops:", this.stops);
|
||||
// console.log("Next stop ID from routeProgress:", nextStopId);
|
||||
// console.log("All stops:", this.stops);
|
||||
|
||||
const nextStop = this.stops.find((stop) => stop.id === nextStopId);
|
||||
console.log("Next stop object:", nextStop);
|
||||
// console.log("Next stop object:", nextStop);
|
||||
|
||||
if (nextStop && nextStop.transfers) {
|
||||
console.log("Transfers at next stop:", nextStop.transfers);
|
||||
// console.log("Transfers at next stop:", nextStop.transfers);
|
||||
this.nextStopTransfers = nextStop.transfers;
|
||||
} else {
|
||||
console.log("No transfers found at next stop");
|
||||
// console.log("No transfers found at next stop");
|
||||
this.nextStopTransfers = null;
|
||||
}
|
||||
},
|
||||
},
|
||||
async mounted() {
|
||||
await this.checkAuth();
|
||||
await this.fetchGeolocationContext();
|
||||
await this.fetchSights();
|
||||
await this.fetchGeolocationContext();
|
||||
this.geolocationInterval = setInterval(() => {
|
||||
this.fetchGeolocationContext();
|
||||
}, 1000);
|
||||
window.addEventListener("mousemove", this.handleUserActivity);
|
||||
window.addEventListener("touchstart", this.handleUserActivity, {
|
||||
passive: true,
|
||||
});
|
||||
window.addEventListener("keydown", this.handleUserActivity);
|
||||
window.addEventListener("click", this.handleUserActivity, true);
|
||||
// this.fetchSightInfo();
|
||||
// this.fetchArticles();
|
||||
},
|
||||
unmounted() {
|
||||
if (this.sightsInactivityTimer) {
|
||||
clearTimeout(this.sightsInactivityTimer);
|
||||
}
|
||||
window.removeEventListener("mousemove", this.handleUserActivity);
|
||||
window.removeEventListener("touchstart", this.handleUserActivity, {
|
||||
passive: true,
|
||||
});
|
||||
window.removeEventListener("keydown", this.handleUserActivity);
|
||||
window.removeEventListener("click", this.handleUserActivity, true);
|
||||
if (this.autoCloseTimer) {
|
||||
clearTimeout(this.autoCloseTimer);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="weatherinfo">
|
||||
<div class="weatherinfo" :class="{ hidden: isPresidentAddressOpen }">
|
||||
<div class="time">{{ formattedTime }}</div>
|
||||
<div class="date">{{ formattedDate }}, {{ dayOfWeek }}</div>
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
alt="Weather Icon"
|
||||
/>
|
||||
<div class="temperature-celsius">
|
||||
{{ currentWeather.temperatureCelsius }}°C
|
||||
{{ currentWeather.temperatureCelsius }}°
|
||||
</div>
|
||||
<div>
|
||||
{{ currentWeather.description }}
|
||||
@ -27,8 +27,8 @@
|
||||
<div class="humidity">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="12"
|
||||
height="16"
|
||||
width="13"
|
||||
height="18"
|
||||
fill="none"
|
||||
viewBox="0 0 12 16"
|
||||
>
|
||||
@ -43,8 +43,8 @@
|
||||
<div class="wind">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="16"
|
||||
height="16"
|
||||
width="18"
|
||||
height="18"
|
||||
fill="none"
|
||||
viewBox="0 0 16 16"
|
||||
>
|
||||
@ -72,8 +72,9 @@
|
||||
|
||||
<script>
|
||||
import "../assets/style/main.css";
|
||||
import { API_URL } from "../config";
|
||||
|
||||
import axios from "axios";
|
||||
import Cookies from "js-cookie";
|
||||
import clearIcon from "@/icons/clear-day.svg";
|
||||
import cloudsIcon from "@/icons/cloudy.svg";
|
||||
import rainIcon from "@/icons/rainy.svg";
|
||||
@ -84,6 +85,12 @@ import fogIcon from "@/icons/fog.svg";
|
||||
|
||||
export default {
|
||||
name: "WeatherInfo",
|
||||
props: {
|
||||
isPresidentAddressOpen: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isModalOpen: false,
|
||||
@ -101,55 +108,24 @@ export default {
|
||||
dayOfWeek: "",
|
||||
timerInterval: null,
|
||||
weatherDescriptionMap: {
|
||||
thunderstorm: "Гроза",
|
||||
drizzle: "Слабый дождь",
|
||||
rain: "Дождь",
|
||||
snow: "Снег",
|
||||
atmosphere: "Туман",
|
||||
clear: "Ясно",
|
||||
clouds: "Облачно",
|
||||
thunderstorm: "гроза",
|
||||
drizzle: "слабый дождь",
|
||||
rain: "дождь",
|
||||
snow: "снег",
|
||||
atmosphere: "туман",
|
||||
clear: "ясно",
|
||||
clouds: "облачно",
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async getToken() {
|
||||
let token = Cookies.get("auth_token");
|
||||
try {
|
||||
await axios.get("https://wn-ts.krbl.ru/auth/me", {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
} catch (error) {
|
||||
if (error.response && error.response.status === 401) {
|
||||
const response = await axios.post(
|
||||
"https://wn-ts.krbl.ru/auth/login",
|
||||
{
|
||||
email: "admin",
|
||||
password: "changeme",
|
||||
}
|
||||
);
|
||||
token = response.data.token;
|
||||
Cookies.set("auth_token", token);
|
||||
}
|
||||
}
|
||||
return token;
|
||||
},
|
||||
async fetchSightInfo() {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.get(
|
||||
`https://wn-ts.krbl.ru/sight/${this.sightId}`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
);
|
||||
const response = await axios.get(`${API_URL}/sight/${this.sightId}`);
|
||||
this.stopName = response.data.name;
|
||||
},
|
||||
async fetchArticles() {
|
||||
const token = await this.getToken();
|
||||
const response = await axios.get(
|
||||
`https://wn-ts.krbl.ru/sight/${this.sightId}/article`,
|
||||
{
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
}
|
||||
`${API_URL}/sight/${this.sightId}/article`
|
||||
);
|
||||
this.articles = response.data;
|
||||
if (this.articles.length > 0) {
|
||||
|
2
src/config.js
Normal file
2
src/config.js
Normal file
@ -0,0 +1,2 @@
|
||||
export const API_URL = process.env.VUE_APP_API_URL;
|
||||
export const GEO_URL = process.env.VUE_APP_GEO_URL;
|
35
src/icons/tram-bottom-left.svg
Normal file
35
src/icons/tram-bottom-left.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
35
src/icons/tram-bottom-right.svg
Normal file
35
src/icons/tram-bottom-right.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
35
src/icons/tram-left.svg
Normal file
35
src/icons/tram-left.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
35
src/icons/tram-right.svg
Normal file
35
src/icons/tram-right.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
35
src/icons/tram-top-left.svg
Normal file
35
src/icons/tram-top-left.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
35
src/icons/tram-top-right.svg
Normal file
35
src/icons/tram-top-right.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 63 KiB |
Loading…
Reference in New Issue
Block a user