._.
This commit is contained in:
parent
7eda0718a8
commit
9b67ebf431
@ -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;
|
||||||
|
}
|
||||||
|
|||||||
48
WEB/app/src/app/components/сalendar.js
Normal file
48
WEB/app/src/app/components/сalendar.js
Normal 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;
|
||||||
@ -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>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user