Files
ntspi-app/resources/js/Pages/Client/Tv/Time.vue
T

187 lines
6.1 KiB
Vue

<template>
<div
class="text-white min-h-screen flex font-sans transition-all duration-500"
:class="{ 'invert': isResetting }"
>
<!-- Левый блок - Расписание -->
<div class="w-1/2 p-10 flex flex-col justify-center bg-gray-900">
<!-- Состояние: Идет пара -->
<div v-if="currentStatus.type === 'class'">
<h2 class="text-6xl font-bold mb-4">
Идет {{ currentStatus.number }} пара
</h2>
<p class="text-4xl tabular-nums">
Осталось: {{ currentStatus.remaining }}
</p>
</div>
<!-- Состояние: Идет перемена -->
<div v-else-if="currentStatus.type === 'break'">
<h2 class="text-6xl font-bold mb-4">
Перемена
</h2>
<p class="text-4xl tabular-nums">
До начала {{ currentStatus.nextClassNumber }} пары: {{ currentStatus.untilNext }}
</p>
</div>
<!-- Состояние: До начала пар -->
<div v-else-if="currentStatus.type === 'before_classes'">
<h2 class="text-5xl font-bold text-center mb-3">Пары еще не начались</h2>
<p class="text-4xl tabular-nums text-center">
До начала первой пары: {{ currentStatus.untilNext }}
</p>
</div>
<!-- Состояние: Пары закончились -->
<div v-else>
<h2 class="text-5xl font-bold">
Пары на сегодня закончены
</h2>
</div>
</div>
<!-- Правый блок - Дата и время -->
<div class="w-1/2 bg-gray-800 p-10 flex flex-col justify-center items-center">
<h1 class="text-8xl font-bold mb-4 tabular-nums">
{{ currentTime }}
</h1>
<p class="text-4xl">
{{ currentDate }}
</p>
</div>
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted, computed } from 'vue';
// --- НОВОЕ: Состояние для эффекта сброса ---
const isResetting = ref(false);
// --- Дата и время ---
const now = ref(new Date());
const currentTime = computed(() => {
return now.value.toLocaleTimeString('ru-RU', {
hour: '2-digit',
minute: '2-digit',
second: '2-digit'
});
});
const currentDate = computed(() => {
return now.value.toLocaleDateString('ru-RU', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
});
});
let timer;
// --- НОВОЕ: Переменная для таймера сброса ---
let resetInterval;
onMounted(() => {
// Устанавливаем таймер для обновления времени каждую секунду
timer = setInterval(() => {
now.value = new Date();
}, 1000);
// --- НОВОЕ: Запускаем таймер для эффекта сброса ---
// Срабатывает каждые 15 минут
resetInterval = setInterval(() => {
isResetting.value = !isResetting.value;
}, 900000); // 15 минут = 900 000 мс
});
onUnmounted(() => {
// Очищаем таймер при уничтожении компонента
clearInterval(timer);
// --- НОВОЕ: Очищаем таймер сброса ---
clearInterval(resetInterval);
});
// --- Расписание на основе документа ---
const schedule = [
{ number: '1', start: '09:00', end: '10:30' },
{ number: '2', start: '10:40', end: '12:10' },
{ number: '3', start: '13:00', end: '14:30' },
{ number: '4', start: '14:40', end: '16:10' },
{ number: '5', start: '16:20', end: '17:50' },
{ number: '6', start: '18:00', end: '19:30' },
];
// Вспомогательная функция для преобразования времени 'ЧЧ:ММ' в объект Date
const parseTime = (timeStr) => {
const [hours, minutes] = timeStr.split(':').map(Number);
const date = new Date();
date.setHours(hours, minutes, 0, 0);
return date;
};
// Вспомогательная функция для форматирования миллисекунд в 'ЧЧ:ММ:СС'
const formatDuration = (ms) => {
if (ms < 0) ms = 0;
const totalSeconds = Math.floor(ms / 1000);
const hours = Math.floor(totalSeconds / 3600);
const minutes = Math.floor((totalSeconds % 3600) / 60);
const seconds = totalSeconds % 60;
return [
hours.toString().padStart(2, '0'),
minutes.toString().padStart(2, '0'),
seconds.toString().padStart(2, '0')
].join(':');
};
// Главная вычисляемая переменная, определяющая текущий статус
const currentStatus = computed(() => {
const currentTime = now.value;
const firstClassTime = parseTime(schedule[0].start);
// Проверка, если еще до начала первой пары
if (currentTime < firstClassTime) {
const untilNextMs = firstClassTime - currentTime;
return {
type: 'before_classes',
untilNext: formatDuration(untilNextMs)
};
}
for (let i = 0; i < schedule.length; i++) {
const lesson = schedule[i];
const startTime = parseTime(lesson.start);
const endTime = parseTime(lesson.end);
// Проверка, идет ли сейчас пара
if (currentTime >= startTime && currentTime < endTime) {
const remainingMs = endTime - currentTime;
return {
type: 'class',
number: lesson.number,
remaining: formatDuration(remainingMs),
};
}
// Проверка, идет ли сейчас перемена
if (i < schedule.length - 1) {
const nextLesson = schedule[i + 1];
const nextStartTime = parseTime(nextLesson.start);
if (currentTime >= endTime && currentTime < nextStartTime) {
const untilNextMs = nextStartTime - currentTime;
return {
type: 'break',
untilNext: formatDuration(untilNextMs),
nextClassNumber: nextLesson.number,
};
}
}
}
// Если ни одно из условий не выполнилось, значит пары закончились
return { type: 'finished' };
});
</script>