This commit is contained in:
Андрей Дувакин 2025-01-28 18:51:35 +05:00
parent 7eda0718a8
commit 9b67ebf431
3 changed files with 252 additions and 148 deletions

View File

@ -110,8 +110,8 @@
.calendar { .calendar {
margin: 2vw; margin: 2vw;
border: 1px solid black;
height: 25vw; height: 25vw;
padding: 2vw;
} }
.events { .events {
@ -131,3 +131,56 @@
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
} }
.calendar-container {
width: 350px;
text-align: center;
font-family: Arial, sans-serif;
}
.calendar-header {
display: flex;
justify-content: space-between;
align-items: center;
background-color: #2f9836;
color: white;
padding: 10px;
border-radius: 8px;
}
.calendar-header button {
background: none;
border: none;
color: white;
font-size: 20px;
cursor: pointer;
}
.calendar-grid {
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 5px;
margin-top: 10px;
}
.calendar-weekday {
font-weight: bold;
text-align: center;
}
.calendar-day, .empty-cell {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 5px;
}
.calendar-day {
cursor: pointer;
}
.calendar-day:hover {
background-color: #cfcfcf;
}

View File

@ -0,0 +1,48 @@
'use client';
import {useState} from "react";
const Calendar = () => {
const [currentDate, setCurrentDate] = useState(new Date());
const year = currentDate.getFullYear();
const month = currentDate.getMonth();
const prevMonth = () => setCurrentDate(new Date(year, month - 1, 1));
const nextMonth = () => setCurrentDate(new Date(year, month + 1, 1));
const generateCalendar = () => {
const firstDayOfMonth = new Date(year, month, 1).getDay(); // День недели 1-го числа (0 - воскресенье)
const daysInMonth = new Date(year, month + 1, 0).getDate(); // Количество дней в месяце
const startOffset = firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1;
const daysArray = Array.from({length: daysInMonth}, (_, i) => i + 1);
return [...Array(startOffset).fill(null), ...daysArray];
};
const days = generateCalendar();
const weekDays = ["Пн", "Вт", "Ср", "Чт", "Пт", "Сб", "Вс"];
return (
<div className="calendar-container">
<div className="calendar-header">
<button onClick={prevMonth}>{"<"}</button>
<h2>{currentDate.toLocaleString("ru-RU", {month: "long", year: "numeric"})}</h2>
<button onClick={nextMonth}>{">"}</button>
</div>
<div className="calendar-grid">
{weekDays.map((day) => (
<div key={day} className="calendar-weekday">{day}</div>
))}
{days.map((day, index) =>
day ? <div key={index} className="calendar-day">{day}</div> :
<div key={index} className="empty-cell"></div>
)}
</div>
</div>
);
};
export default Calendar;

View File

@ -3,170 +3,173 @@
import './app.css'; import './app.css';
import Header from './components/header.js'; import Header from './components/header.js';
import EmployeeCard from './components/employee-card.js'; import EmployeeCard from './components/employee-card.js';
import { useEffect, useState } from 'react'; import {useEffect, useState} from 'react';
import RSSFeed from './components/news-card.js'; import RSSFeed from './components/news-card.js';
import EventCard from './components/event-card'; import EventCard from './components/event-card';
import Calendar from "./components/сalendar";
export default function Home() { export default function Home() {
const [searchString, setSearchString] = useState(''); const [searchString, setSearchString] = useState('');
const [employees, setEmployees] = useState([]); const [employees, setEmployees] = useState([]);
const [news, setNews] = useState([]); const [news, setNews] = useState([]);
const [events, setEvents] = useState([]); const [events, setEvents] = useState([]);
useEffect(() => { useEffect(() => {
fetchEmployees();
fetchRSS();
fetchEvents();
const interval = setInterval(
() => {
fetchEmployees(); fetchEmployees();
fetchRSS(); fetchRSS();
fetchEvents(); fetchEvents();
}, 5000
)
return () => { const interval = setInterval(
clearInterval(interval); () => {
} fetchEmployees();
}, []); fetchRSS();
fetchEvents();
}, 5000
)
useEffect(() => { return () => {
filterData(); clearInterval(interval);
}, [searchString]) }
}, []);
const fetchEmployees = async () => { useEffect(() => {
try { filterData();
const data = await fetch('http://localhost:5000/employees'); }, [searchString])
if (data.ok) { const fetchEmployees = async () => {
const json_data = await data.json(); try {
setEmployees(json_data) const data = await fetch('http://localhost:5000/employees');
}
} catch { if (data.ok) {
const json_data = await data.json();
setEmployees(json_data)
}
} } catch {
}
const fetchEvents = async () => { }
try {
const data = await fetch('http://localhost:5000/events');
if (data.ok) {
const json_data = await data.json();
setEvents(json_data)
}
} catch {
}
}
const fetchRSS = async () => {
try {
const response = await fetch("http://127.0.0.1:5000/rss");
if (response.ok) {
const json_data = await response.json();
setNews(json_data);
}
} catch (error) {
console.error("Ошибка загрузки RSS:", error);
}
};
const filterData = (data, fields) => {
if (data === undefined) {
return data;
} }
if (!searchString.trim()) return data; const fetchEvents = async () => {
try {
const data = await fetch('http://localhost:5000/events');
return data.filter(item => if (data.ok) {
fields.some(field => const json_data = await data.json();
String(item[field] || "").toLowerCase().includes(searchString.toLowerCase()) setEvents(json_data)
) }
} catch {
}
}
const fetchRSS = async () => {
try {
const response = await fetch("http://127.0.0.1:5000/rss");
if (response.ok) {
const json_data = await response.json();
setNews(json_data);
}
} catch (error) {
console.error("Ошибка загрузки RSS:", error);
}
};
const filterData = (data, fields) => {
if (data === undefined) {
return data;
}
if (!searchString.trim()) return data;
return data.filter(item =>
fields.some(field =>
String(item[field] || "").toLowerCase().includes(searchString.toLowerCase())
)
);
};
const filteredEmployees = filterData(employees, ["last_name", "first_name", "patronymic", "post", "email", "phone", "birthday"]);
const filteredEvents = filterData(events, ["title", "description", "author"]);
const filteredNews = filterData(news, ["title", "description"]);
return (
<>
<Header setSearchString={setSearchString}/>
<div className="page">
<div className="user-list">
<h1>
Сотрудники
</h1>
<div className='user-row-list'>
{filteredEmployees.length > 0 ? (
filteredEmployees.map(
(employee) => (
<EmployeeCard key={employee.id} employee={employee}/>
)
)
) : (
<h2>Сотрудники не найдены</h2>
)}
</div>
</div>
<div className="content">
<div className="calendar-and-events">
<div className="calendar">
<h1>
Календарь
</h1>
<Calendar/>
</div>
<div className="events">
<h1>
События
</h1>
{filteredEvents.length > 0 ? (filteredEvents.map(
(event, index) => (
<EventCard key={index} event={event}/>
)
)) : (
<h2>События не найдены</h2>
)}
</div>
</div>
<div className="news">
<h1>
Новости
</h1>
<div className='news-block'>
{filteredNews.length > 0 ? (filteredNews.map((article, index) => (
<RSSFeed key={index} article={article} index={index}/>
))) : (
<h2>Новости не найдены</h2>
)
}
</div>
</div>
</div>
</div>
</>
); );
};
const filteredEmployees = filterData(employees, ["last_name", "first_name", "patronymic", "post", "email", "phone", "birthday"]);
const filteredEvents = filterData(events, ["title", "description", "author"]);
const filteredNews = filterData(news, ["title", "description"]);
return (
<>
<Header setSearchString={setSearchString} />
<div className="page">
<div className="user-list">
<h1>
Сотрудники
</h1>
<div className='user-row-list'>
{filteredEmployees.length > 0 ? (
filteredEmployees.map(
(employee) => (
<EmployeeCard key={employee.id} employee={employee} />
)
)
) : (
<h2>Сотрудники не найдены</h2>
)}
</div>
</div>
<div className="content">
<div className="calendar-and-events">
<div className="calendar">
<h1>
Календарь
</h1>
</div>
<div className="events">
<h1>
События
</h1>
{filteredEvents.length > 0 ? (filteredEvents.map(
(event, index) => (
<EventCard key={index} event={event} />
)
)) : (
<h2>События не найдены</h2>
)}
</div>
</div>
<div className="news">
<h1>
Новости
</h1>
<div className='news-block'>
{filteredNews.length > 0? (filteredNews.map((article, index) => (
<RSSFeed key={index} article={article} index={index} />
))) : (
<h2>Новости не найдены</h2>
)
}
</div>
</div>
</div>
</div>
</>
);
} }