diff --git a/.github/workflows/deploy.yaml b/.github/workflows/deploy.yaml
index f29ac12..dc530c8 100644
--- a/.github/workflows/deploy.yaml
+++ b/.github/workflows/deploy.yaml
@@ -7,8 +7,6 @@ on:
workflows: [build]
types:
- completed
- branches:
- - main
workflow_dispatch:
env:
@@ -16,30 +14,22 @@ env:
SSH_AUTH_SOCK: /tmp/ssh_agent.sock
SSH_HOST: ${{ secrets.SSH_HOST }}
SSH_USER: ${{ secrets.SSH_USER }}
- SSH_PORT: ${{ secrets.SSH_PORT }}
-
+
jobs:
- deploy:
+ build:
runs-on: ubuntu-latest
- if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v2
- run: 'command -v ssh-agent >/dev/null || ( apt-get update -y && apt-get install openssh-client -y )'
- name: Set up SSH private key.
run: eval "$(ssh-agent -s)"
- run: mkdir -p ~/.ssh
- - run: ssh-keyscan -p $SSH_PORT $SSH_HOST >> ~/.ssh/known_hosts
+ - run: ssh-keyscan ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
- run: ssh-agent -a $SSH_AUTH_SOCK > /dev/null
- run: ssh-add - <<< "${{ secrets.SSH_KEY }}"
- - name: Add image tag to .version file
- run: |
- echo $IMAGE_TAG > .version
- scp -P 666 .version $SSH_USER@$SSH_HOST:~/YetAnotherCalendar/.version
-
+
- name: Update docker compose
run: |
- ssh $SSH_USER@$SSH_HOST -p $SSH_PORT "cd YetAnotherCalendar/ && git pull origin main
- YET_ANOTHER_CALENDAR_VERSION=$(cat .version) docker compose -f docker-compose.prod.yaml pull
- YET_ANOTHER_CALENDAR_VERSION=$(cat .version) docker compose -f docker-compose.prod.yaml up -d"
-
\ No newline at end of file
+ ssh $SSH_USER@$SSH_HOST "cd YetAnotherCalendar/ && YET_ANOTHER_CALENDAR_VERSION=$IMAGE_TAG docker compose up -d --build"
+
\ No newline at end of file
diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index caa3691..23562fc 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -20,6 +20,7 @@ const App = () => {
if (response.status === 200) {
setAuthData({email, password, personId});
localStorage.setItem('token', response.data["_netology-on-rails_session"]);
+
return {success: true};
} else {
return {success: false, message: "Неверный логин или пароль."};
diff --git a/frontend/src/components/Calendar/Calendar.jsx b/frontend/src/components/Calendar/Calendar.jsx
index 6fedcd5..c4ec2c3 100644
--- a/frontend/src/components/Calendar/Calendar.jsx
+++ b/frontend/src/components/Calendar/Calendar.jsx
@@ -5,6 +5,9 @@ import cross from "../../img/arrow.png";
import '../../style/header.scss';
import '../../style/calendar.scss';
+import DatePicker from "./DataPicker";
+import camera from "../../img/camera.png";
+
const Calendar = ({events}) => {
console.log('events:', events);
@@ -91,10 +94,9 @@ const Calendar = ({events}) => {
- {/* Информация о дедлайнах */}
-
+
{netology?.homework?.length > 0 && netology.homework.map((homeworkItem, index) => (
-
{
))}
+
+
@@ -126,29 +130,28 @@ const Calendar = ({events}) => {
-
+
|
{weekDays.map((day, index) => (
{day.day} |
))}
- {/*TODO: написать логику*/}
-
-
- дедлайны
-
+ {/*TODO: написать логику*/}
+ |
+ дедлайны
+ Скрыть
|
-
-
+ ТюмГУ
+ Нетология
|
|
-
+ ТюмГУ
|
|
-
+ Нетология
|
|
|
@@ -160,7 +163,7 @@ const Calendar = ({events}) => {
{[1, 2, 3, 4, 5, 6, 7].map((lessonNumber) => (
- {lessonNumber} пара {lessonNumber * 2 + 8}:00 - {lessonNumber * 2 + 9}:30
+ {lessonNumber} пара {lessonNumber * 2 + 8}:00 {lessonNumber * 2 + 9}:30
|
{weekDays.map((day, index) => {
const eventsForDay = getEventsForDay(day.date);
@@ -169,13 +172,14 @@ const Calendar = ({events}) => {
{eventsForSlot.length > 0 ? (
eventsForSlot.map(event => (
-
+
+ ТюмГУ
{event.nameShort}
{event.name}
{new Date(event.start).toLocaleTimeString([], {
- hour: '2-digit',
- minute: '2-digit'
+ hour: '2-digit',
+ minute: '2-digit'
})} -
{new Date(event.end).toLocaleTimeString([], {
hour: '2-digit',
@@ -185,15 +189,16 @@ const Calendar = ({events}) => {
{event.teacher_full_name}
))
- ) : (
-
- )}
- |
- );
- })}
-
- ))}
-
+ ) : (
+ )}
+
+ );
+ })}
+
+ )
+ )
+ }
+
diff --git a/frontend/src/components/Calendar/DataPicker.jsx b/frontend/src/components/Calendar/DataPicker.jsx
index 6bed40b..92660af 100644
--- a/frontend/src/components/Calendar/DataPicker.jsx
+++ b/frontend/src/components/Calendar/DataPicker.jsx
@@ -1,41 +1,67 @@
-import React, { useRef, useEffect, useState } from "react";
-import Flatpickr from "flatpickr";
-import weekSelect from "flatpickr";
+import React, { useEffect, useState } from "react";
import "flatpickr/dist/flatpickr.css";
-import flatpickr from "flatpickr";
-import { Russian } from "flatpickr/dist/l10n/ru.js";
+// import flatpickr from "flatpickr";
+// import { Russian } from "flatpickr/dist/l10n/ru.js";
+import "../../style/DatePicker.scss"; // Для стилей компонента
const DatePicker = () => {
- const datePickerRef = useRef(null);
+ // const datePickerRef = useRef(null);
+ const [currentDate, setCurrentDate] = useState(new Date()); // Текущая дата
+ const [weekRange, setWeekRange] = useState("");
- const [dateOnCalendar, setDateOnCalendar] = useState("2024-09-19");
- const [weekNumber, setWeekNumber] = useState(null);
+ // Рассчитать начало и конец недели
+ const calculateWeekRange = (date) => {
+ const startOfWeek = new Date(date);
+ const endOfWeek = new Date(date);
+ // Получаем понедельник текущей недели
+ startOfWeek.setDate(date.getDate() - date.getDay() + 1); // Понедельник
+ endOfWeek.setDate(startOfWeek.getDate() + 6); // Воскресенье
+
+ const formatOptions = { day: "numeric", month: "long" };
+ const startFormatted = startOfWeek.toLocaleDateString("ru-RU", formatOptions);
+ const endFormatted = endOfWeek.toLocaleDateString("ru-RU", formatOptions);
+
+ return `${startFormatted} – ${endFormatted}`;
+ };
+
+ // Обновить диапазон недели при изменении даты
useEffect(() => {
- flatpickr(datePickerRef.current, {
- locale: Russian,
- onChange: [
- () => {
- setWeekNumber(
- this.selectedDates[0] ? setWeekNumber(this.selectedDates[0]) : null,
- );
- console.log(weekNumber);
- },
- ],
+ setWeekRange(calculateWeekRange(currentDate));
+ }, [currentDate]);
+
+ // Обработчик для переключения недель
+ const handlePrevWeek = () => {
+ setCurrentDate((prevDate) => {
+ const newDate = new Date(prevDate);
+ newDate.setDate(prevDate.getDate() - 7); // Переключение на предыдущую неделю
+ return newDate;
});
- }, []);
+ };
+
+ const handleNextWeek = () => {
+ setCurrentDate((prevDate) => {
+ const newDate = new Date(prevDate);
+ newDate.setDate(prevDate.getDate() + 7); // Переключение на следующую неделю
+ return newDate;
+ });
+ };
return (
-
-
setDateOnCalendar(e.target.value)}
- />
+
+
+
{weekRange}
+
+
+
+
+
);
};
-flatpickr.l10ns.default.firstDayOfWeek = 1;
+
export default DatePicker;
diff --git a/frontend/src/components/Calendar/exportICS.jsx b/frontend/src/components/Calendar/exportICS.jsx
new file mode 100644
index 0000000..e69de29
diff --git a/frontend/src/components/Header/Header.js b/frontend/src/components/Header/Header.js
index aa61965..a5a592c 100644
--- a/frontend/src/components/Header/Header.js
+++ b/frontend/src/components/Header/Header.js
@@ -23,15 +23,18 @@ export default function Header() {
-
-
-
Дедлайн Нетология
23.09.2024
-
-
- Программирование на Python
-
-
-
Домашнее задание с самопроверкой(дедлайн 12.12.24)
+
+
+
+
Дедлайн Нетология
23.09.2024
+
+
+ Программирование на Python
+
+
+ Домашнее задание с самопроверкой(дедлайн 12.12.24)
+
@@ -48,7 +51,7 @@ export default function Header() {
Вс 29.09 |
-
+ |
дедлайны
|
@@ -71,9 +74,12 @@ export default function Header() {
|
|
|
- |
|
diff --git a/frontend/src/pages/CalendarRoute.jsx b/frontend/src/pages/CalendarRoute.jsx
index 83067f4..b2548cd 100644
--- a/frontend/src/pages/CalendarRoute.jsx
+++ b/frontend/src/pages/CalendarRoute.jsx
@@ -1,7 +1,7 @@
import React, { useEffect, useState } from 'react';
import { getNetologyCourse, bulkEvents } from '../services/api'; // Ваши API-запросы
import Calendar from "../components/Calendar/Calendar";
-// import Header from "../components/Header/Header";
+import Header from "../components/Header/Header";
const CalendarRoute = ({ email, password, personId, token }) => {
const [events, setEvents] = useState(null);
@@ -42,21 +42,25 @@ const CalendarRoute = ({ email, password, personId, token }) => {
const courseData = await getNetologyCourse(token);
console.log('Данные курса:', courseData);
- const fetchedCalendarId = courseData?.id;
+ const calendarId = courseData?.id;
+ console.log('calendarId add storage', calendarId)
+ localStorage.setItem('calendarId', calendarId);
- if (fetchedCalendarId) {
+ if (calendarId) {
const eventsResponse = await bulkEvents(
email, // Email пользователя
password, // Пароль пользователя
token, // Токен сессии
- fetchedCalendarId, // ID календаря
+ calendarId, // ID календаря
"2024-10-14T00:00:00+03:00", // Дата начала
"2024-10-20T23:59:59+03:00", // Дата окончания
personId // ID участника
);
console.log('События:', eventsResponse.data);
setEvents(eventsResponse.data);
-
+ // cached_at
+ localStorage.setItem('cached_at', eventsResponse.data.cached_at); // Сохраняем cached_at localstorage
+ console.log('eventsResponse.data.cached_at', eventsResponse.data.cached_at)
// Сохраняем события в localStorage
saveEventsToLocalStorage(eventsResponse.data);
}
@@ -82,7 +86,7 @@ const CalendarRoute = ({ email, password, personId, token }) => {
return (
- {/**/}
+
);
};
diff --git a/frontend/src/pages/LoginRoute.jsx b/frontend/src/pages/LoginRoute.jsx
index c3afbf1..c0b0617 100644
--- a/frontend/src/pages/LoginRoute.jsx
+++ b/frontend/src/pages/LoginRoute.jsx
@@ -49,6 +49,7 @@ const LoginRoute = ({onLogin, onSearch}) => {
const handleSelect = (person) => {
setFullName(person.fullName); // Устанавливаем выбранное имя
setPersonId(person.personId); // Сохраняем personId
+ localStorage.setItem('personId', personId); // Сохраняем personId localstorage
setShowSuggestions(false); // Скрываем список после выбора
};
diff --git a/frontend/src/services/api.js b/frontend/src/services/api.js
index 9793c54..ed3affd 100644
--- a/frontend/src/services/api.js
+++ b/frontend/src/services/api.js
@@ -93,4 +93,28 @@ export async function refreshBulkEvents(sessionToken, calendarId, timeMin, timeM
}
}
+// export file
+export async function exportICS(sessionToken, calendarId, timeMin, timeMax, attendeePersonId) {
+ try {
+ const response = await axios.post(
+ `${BACKEND_URL}/api/bulk/export_ics/?calendar_id=${calendarId}`, // URL с calendar_id в параметрах
+ {
+ timeMin,
+ timeMax,
+ size: 50,
+ attendeePersonId: [attendeePersonId],
+ },
+ {
+ headers: {
+ "_netology-on-rails_session": sessionToken, // Токен сессии
+ "Content-Type": "application/json",
+ "time_zone": "Europe/Moscow", // Добавляем time_zone в заголовки
+ },
+ }
+ );
+ return response;
+ } catch (e) {
+ return e.response;
+ }
+}
diff --git a/frontend/src/style/DatePicker.scss b/frontend/src/style/DatePicker.scss
new file mode 100644
index 0000000..a423e45
--- /dev/null
+++ b/frontend/src/style/DatePicker.scss
@@ -0,0 +1,40 @@
+.date-picker-wrapper {
+ width: fit-content;
+ margin-left: auto;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ padding: 10px;
+ background-color: #f3f4f6;
+ border-radius: 8px;
+ font-family: Arial, sans-serif;
+}
+
+.week-display {
+ display: flex;
+ align-items: center;
+}
+
+.week-range {
+ font-size: 16px;
+ font-weight: bold;
+}
+
+.week-navigation {
+ display: flex;
+ margin-left: 10px;
+}
+
+.prev-week-btn, .next-week-btn {
+ background-color: #e0e0e0;
+ border: none;
+ padding: 5px 10px;
+ margin: 0 5px;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 16px;
+}
+
+.prev-week-btn:hover, .next-week-btn:hover {
+ background-color: #d0d0d0;
+}
diff --git a/frontend/src/style/calendar.scss b/frontend/src/style/calendar.scss
index e5b8648..e0fd383 100644
--- a/frontend/src/style/calendar.scss
+++ b/frontend/src/style/calendar.scss
@@ -1,48 +1,47 @@
-//&-info {
-// height: 28px;
-// margin-top: 6px;
-// width: 95%;
-// text-align: left;
-// padding: 5px 11px;
-// border: none;
-// background: #F46386;
-// border-radius: 6px;
-// color: #fff;
-// font-family: "Roboto", sans-serif;
-// font-weight: 700;
-// font-size: 13px;
-// transition: color 0.3s linear;
-//
-// &:hover {
-// cursor: pointer;
-// color: #F46386;
-// background-color: #fff;
-// border: 2px solid #F46386;
-// }
-// }
-
-//&-info-on {
-// height: 28px;
-// margin-top: 4px;
-// width: 95%;
-// text-align: left;
-// padding: 5px 11px;
-// color: #F46386;
-// background-color: #fff;
-// border: 2px solid #F46386;
-// border-radius: 6px;
-// font-family: "Roboto", sans-serif;
-// font-weight: 700;
-// font-size: 13px;
-// transition: color 0.3s linear;
-//
-// &:hover {
-// cursor: pointer;
-// color: #fff;
-// background-color: #F46386;
-// border: none;
-// }
-// }
+.deadline {
+ &-info {
+ height: 28px;
+ margin-top: 6px;
+ width: 95%;
+ text-align: left;
+ padding: 5px 11px;
+ border: none;
+ background: #F46386;
+ border-radius: 6px;
+ color: #fff;
+ font-family: "Roboto", sans-serif;
+ font-weight: 700;
+ font-size: 13px;
+ transition: color 0.3s linear;
+ &:hover {
+ cursor: pointer;
+ color: #F46386;
+ background-color: #fff;
+ border: 2px solid #F46386;
+ }
+ }
+ &-info-on {
+ height: 28px;
+ margin-top: 4px;
+ width: 95%;
+ text-align: left;
+ padding: 5px 11px;
+ color: #F46386;
+ background-color: #fff;
+ border: 2px solid #F46386;
+ border-radius: 6px;
+ font-family: "Roboto", sans-serif;
+ font-weight: 700;
+ font-size: 13px;
+ transition: color 0.3s linear;
+ &:hover {
+ cursor: pointer;
+ color: #fff;
+ background-color: #F46386;
+ border: none;
+ }
+ }
+}
.shedule-table {
width: 100%;
diff --git a/frontend/src/style/header.scss b/frontend/src/style/header.scss
index d02a8e9..ad78dbb 100644
--- a/frontend/src/style/header.scss
+++ b/frontend/src/style/header.scss
@@ -19,8 +19,9 @@
align-items: center;
margin-bottom: 22px;
}
+}
- &-deadline {
+.rectangle {
display: flex;
justify-content: flex-end;
flex-direction: row-reverse;
@@ -39,7 +40,6 @@
text-decoration: none;
}
}
-}
.shedule-export {
@@ -210,22 +210,22 @@
text-align: left;
}
-.calendar-date {
- position: absolute;
- top: 165px;
- right: 248px;
- background-color: #ecedf0;
- width: 406px;
- height: 32px;
- border-radius: 6px;
- border: 1px solid rgba(217, 217, 217, 0.5);
- font-family: "Unbounded", sans-serif;
- font-weight: 500;
- font-size: 15px;
- padding-left: 14px;
- transition: color 0.2s linear;
-
- &:hover {
- background-color: #e7e7ea;
- }
-}
\ No newline at end of file
+//.calendar-date {
+// position: absolute;
+// top: 165px;
+// right: 248px;
+// background-color: #ecedf0;
+// width: 406px;
+// height: 32px;
+// border-radius: 6px;
+// border: 1px solid rgba(217, 217, 217, 0.5);
+// font-family: "Unbounded", sans-serif;
+// font-weight: 500;
+// font-size: 15px;
+// padding-left: 14px;
+// transition: color 0.2s linear;
+//
+// &:hover {
+// background-color: #e7e7ea;
+// }
+//}
\ No newline at end of file