Compare commits

...

2 Commits

Author SHA1 Message Date
Archibald
49cc307f2c Merge remote-tracking branch 'gittea/main'
# Conflicts:
#	API/app/infrastructure/teams_service.py
2025-06-09 21:45:49 +05:00
Archibald
e6cd2049e0 автоподстановка homepage 2025-06-09 21:45:25 +05:00
3 changed files with 91 additions and 33 deletions

View File

@ -4,7 +4,7 @@ import CONFIG from '@/core/config.js';
const downloadProjectFile = async (fileId) => {
try {
const response = await axios.get(
`${CONFIG.BASE_URL}/project_files/${fileId}/download`,
`${CONFIG.BASE_URL}/project_files/${fileId}/download/`,
{
responseType: 'blob',
withCredentials: true,

View File

@ -9,7 +9,7 @@ const uploadProjectFile = async (projectId, file) => {
formData.append("file", file);
const response = await axios.post(
`${CONFIG.BASE_URL}/project_files/projects/${projectId}/upload`,
`${CONFIG.BASE_URL}/project_files/projects/${projectId}/upload/`,
formData,
{
headers: {
@ -36,4 +36,4 @@ const uploadProjectFile = async (projectId, file) => {
}
};
export default uploadProjectFile;
export default uploadProjectFile;

View File

@ -2,13 +2,13 @@
<q-page class="home-page bg-violet-strong q-pa-md">
<div class="flex justify-center q-mb-md">
<q-avatar size="140px" class="team-logo shadow-12">
<q-avatar v-if="teamLogo" size="140px" class="team-logo shadow-12">
<img :src="teamLogo" alt="Логотип команды"/>
</q-avatar>
</div>
<div class="flex justify-center q-mb-xl">
<q-card class="team-name-card">
<q-card v-if="teamName" class="team-name-card">
<q-card-section class="text-h4 text-center text-indigo-10 q-pa-md">
{{ teamName }}
</q-card-section>
@ -122,13 +122,16 @@
</template>
<script setup>
import {ref, computed, onMounted} from 'vue'
import {useRouter} from 'vue-router'
import {Ripple, Notify} from 'quasar'
import axios from "axios";
import CONFIG from "@/core/config.js";
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { Ripple, Notify } from 'quasar'
import axios from 'axios'
import CONFIG from '@/core/config.js'
import fetchTeams from '@/api/teams/getTeams.js'
import fetchProfiles from '@/api/profiles/getProfiles.js'
import fetchContests from '@/api/contests/getContests.js'
defineExpose({directives: {ripple: Ripple}})
defineExpose({ directives: { ripple: Ripple } })
const router = useRouter()
@ -151,32 +154,21 @@ const handleAuthAction = () => {
}
// --- Данные команды ---
const teamLogo = ref('https://cdn.quasar.dev/logo-v2/svg/logo.svg')
const teamName = ref('Digital Dream Team')
const teamLogo = ref('')
const teamName = ref('')
// --- Участники ---
const members = ref([
{id: 1, name: 'Иван Иванов', role: 'Team Lead', avatar: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?q=80&w=1974&auto=format&fit=crop&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'},
{id: 2, name: 'Мария Петрова', role: 'Frontend', avatar: 'https://randomuser.me/api/portraits/women/44.jpg'},
{id: 3, name: 'Алексей Смирнов', role: 'Backend', avatar: 'https://randomuser.me/api/portraits/men/65.jpg'},
{id: 4, name: 'Анна Кузнецова', role: 'Designer', avatar: 'https://randomuser.me/api/portraits/women/56.jpg'},
{id: 5, name: 'Дмитрий Орлов', role: 'QA', avatar: 'https://randomuser.me/api/portraits/men/78.jpg'},
])
const members = ref([])
// --- Конкурсы ---
const contests = ref([
{id: 1, title: 'Hackathon 2024', description: 'Ежегодный хакатон для стартапов'},
{id: 2, title: 'CodeFest', description: 'Соревнование по программированию'},
{id: 3, title: 'UI/UX Challenge', description: 'Конкурс дизайна интерфейсов'},
{id: 4, title: 'AI Innovation', description: 'Инициатива в области искусственного интеллекта'},
])
const contests = ref([])
// --- Активность ---
const activityData = ref([]);
const dayHeight = 14;
const squareSize = ref(12);
// Подписи месяцев (с июня 2024 по май 2025, чтобы соответствовать текущему году)
// Подписи месяцев (с июня 2024 по май 2025)
const monthLabels = ['июн.', 'июл.', 'авг.', 'сент.', 'окт.', 'нояб.', 'дек.', 'янв.', 'февр.', 'март', 'апр.', 'май'];
// Дни недели (пн, ср, пт, как в Gitea)
@ -186,7 +178,9 @@ const weekDays = ['пн', 'ср', 'пт'];
const activityGrid = computed(() => {
const weeks = [];
let week = [];
const firstDay = new Date();
const firstDay
= new Date();
firstDay.setDate(firstDay.getDate() - 364); // Год назад от текущей даты
const dayOfWeek = firstDay.getDay();
const offset = dayOfWeek === 0 ? 6 : dayOfWeek - 1; // Смещение для выравнивания по понедельнику
@ -228,7 +222,71 @@ function getMonthMargin(idx) {
return weekIndex * (squareSize.value + 4); // 4 = margin (2px + 2px)
}
// Загрузка активности из API
// Загрузка данных команды
async function loadTeamData() {
try {
const teams = await fetchTeams();
const activeTeam = teams.find(team => team.is_active === true);
if (activeTeam) {
teamName.value = activeTeam.name;
teamLogo.value = activeTeam.logo;
} else {
Notify.create({
type: 'warning',
message: 'Активная команда не найдена',
icon: 'warning',
});
}
} catch (error) {
console.error('Ошибка загрузки данных команды:', error);
Notify.create({
type: 'negative',
message: 'Ошибка загрузки данных команды',
icon: 'error',
});
}
}
// Загрузка участников
async function loadMembers() {
try {
const profiles = await fetchProfiles();
members.value = profiles.map(profile => ({
id: profile.id,
name: profile.name || 'Без имени',
role: profile.role || 'Участник',
avatar: profile.avatar || 'https://randomuser.me/api/portraits/men/1.jpg',
}));
} catch (error) {
console.error('Ошибка загрузки участников:', error);
Notify.create({
type: 'negative',
message: error.message || 'Ошибка загрузки участников',
icon: 'error',
});
}
}
// Загрузка конкурсов
async function loadContests() {
try {
const fetchedContests = await fetchContests();
contests.value = fetchedContests.map(contest => ({
id: contest.id,
title: contest.title || 'Без названия',
description: contest.description || 'Описание отсутствует',
}));
} catch (error) {
console.error('Ошибка загрузки конкурсов:', error);
Notify.create({
type: 'negative',
message: error.message || 'Ошибка загрузки конкурсов',
icon: 'error',
});
}
}
// Загрузка активности
const username = 'archibald';
async function loadActivity() {
@ -249,7 +307,7 @@ async function loadActivity() {
date.setDate(startDate.getDate() + i);
const dateStr = date.toISOString().slice(0, 10);
const count = dataMap.get(dateStr) || 0;
activityData.value.push({date: dateStr, count});
activityData.value.push({ date: dateStr, count });
}
} catch (error) {
console.error('Ошибка загрузки активности:', error);
@ -268,13 +326,13 @@ async function loadActivity() {
const date = new Date(startDate);
date.setDate(startDate.getDate() + i);
const dateStr = date.toISOString().slice(0, 10);
activityData.value.push({date: dateStr, count: 0});
activityData.value.push({ date: dateStr, count: 0 });
}
}
}
onMounted(() => {
loadActivity();
onMounted(async () => {
await Promise.all([loadTeamData(), loadMembers(), loadContests(), loadActivity()]);
});
// Масштабирование