mirror of
https://gitlab.com/megazordpobeda/DataRush.git
synced 2026-05-23 02:47:10 +00:00
Merge branch 'master' of gitlab.prodcontest.ru:team-15/project
This commit is contained in:
@@ -82,20 +82,20 @@ class CompetitionTask(BaseModel):
|
|||||||
|
|
||||||
def clean(self):
|
def clean(self):
|
||||||
super().clean()
|
super().clean()
|
||||||
if self.correct_answer_file and self.type not in ["checker", "input"]:
|
# if self.correct_answer_file and self.type not in ["checker", "input"]:
|
||||||
raise ValidationError({
|
# raise ValidationError({
|
||||||
"type": "Если загружен файл правильного ответа, то тип проверки не может быть ручным"
|
# "type": "Если загружен файл правильного ответа, то тип проверки не может быть ручным"
|
||||||
})
|
# })
|
||||||
elif not self.correct_answer_file and self.type == "review":
|
if not self.correct_answer_file and self.type != "review":
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
"correct_answer_file": "Загрузите правильный ответ"
|
"correct_answer_file": "Загрузите правильный ответ"
|
||||||
})
|
})
|
||||||
|
|
||||||
if self.answer_file_path and not self.type == "checker":
|
# if self.answer_file_path and not self.type == "checker":
|
||||||
raise ValidationError({
|
# raise ValidationError({
|
||||||
"type": "Укажите другой тип задания: этот не совместим с путем правильного ответа"
|
# "type": "Укажите другой тип задания: этот не совместим с путем правильного ответа"
|
||||||
})
|
# })
|
||||||
elif not self.answer_file_path and self.type == "checker":
|
if not self.answer_file_path and self.type == "checker":
|
||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
"answer_file_path": "Введите путь правильного ответа - это нужно для корректной работы чекера"
|
"answer_file_path": "Введите путь правильного ответа - это нужно для корректной работы чекера"
|
||||||
})
|
})
|
||||||
@@ -104,10 +104,10 @@ class CompetitionTask(BaseModel):
|
|||||||
raise ValidationError({
|
raise ValidationError({
|
||||||
"reviewers": "Загрузите ревьюверов - кто будет проверять задания, если не они?"
|
"reviewers": "Загрузите ревьюверов - кто будет проверять задания, если не они?"
|
||||||
})
|
})
|
||||||
elif self.reviewers and not self.type == "review":
|
# elif self.reviewers and not self.type == "review":
|
||||||
raise ValidationError({
|
# raise ValidationError({
|
||||||
"type": "Проверьте тип - вы ввели ревьюверов, но задание не является ручным"
|
# "type": "Проверьте тип - вы ввели ревьюверов, но задание не является ручным"
|
||||||
})
|
# })
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ export const Header = () => {
|
|||||||
<div className="md:hidden">
|
<div className="md:hidden">
|
||||||
<Link to="/docs">
|
<Link to="/docs">
|
||||||
<DropdownMenuItem>
|
<DropdownMenuItem>
|
||||||
<FileText className="h-4 w-4 mr-2" />
|
|
||||||
Материалы
|
Материалы
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</Link>
|
</Link>
|
||||||
|
|||||||
@@ -25,14 +25,7 @@ const TaskContent: React.FC<TaskContentProps> = ({ task }) => {
|
|||||||
|
|
||||||
const attachments = attachmentsQuery.data || [];
|
const attachments = attachmentsQuery.data || [];
|
||||||
|
|
||||||
const convertToMarkdown = (text: string): string => {
|
|
||||||
if (!text) return '';
|
|
||||||
|
|
||||||
let markdown = text.replace(/\n/g, '\n\n');
|
|
||||||
return markdown;
|
|
||||||
};
|
|
||||||
|
|
||||||
const markdownText = convertToMarkdown(task.description);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex-1 bg-white rounded-lg p-6">
|
<div className="flex-1 bg-white rounded-lg p-6">
|
||||||
@@ -45,7 +38,7 @@ const TaskContent: React.FC<TaskContentProps> = ({ task }) => {
|
|||||||
remarkPlugins={[remarkMath, remarkGfm]}
|
remarkPlugins={[remarkMath, remarkGfm]}
|
||||||
rehypePlugins={[rehypeKatex]}
|
rehypePlugins={[rehypeKatex]}
|
||||||
>
|
>
|
||||||
{markdownText}
|
{task.description}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,6 @@ const CompetitionSession = () => {
|
|||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
window.location.reload();
|
window.location.reload();
|
||||||
setIsReloading(false);
|
|
||||||
}, 2500);
|
}, 2500);
|
||||||
},
|
},
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
@@ -69,7 +68,9 @@ const CompetitionSession = () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const competition = competitionQuery.data;
|
const competition = competitionQuery.data;
|
||||||
const tasks = tasksQuery.data || [];
|
const tasks = [...(tasksQuery.data || [])].sort((a, b) => {
|
||||||
|
return a.in_competition_position - b.in_competition_position;
|
||||||
|
});
|
||||||
const results = resultsQuery.data || [];
|
const results = resultsQuery.data || [];
|
||||||
const isLoading = tasksQuery.isLoading || competitionQuery.isLoading;
|
const isLoading = tasksQuery.isLoading || competitionQuery.isLoading;
|
||||||
const error = tasksQuery.error || competitionQuery.error
|
const error = tasksQuery.error || competitionQuery.error
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ export function CompetitionCard({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Card
|
<Card
|
||||||
className={cn("aspect-square h-full w-auto overflow-hidden", className)}
|
className={cn("h-full w-full overflow-hidden flex flex-col", className)}
|
||||||
>
|
>
|
||||||
<div className="relative h-full overflow-hidden">
|
<div className="h-48 overflow-hidden">
|
||||||
<img
|
<img
|
||||||
src={competition.image_url ? competition.image_url : '/DANO.png'}
|
src={competition.image_url ? competition.image_url : '/DANO.png'}
|
||||||
alt={competition.title}
|
alt={competition.title}
|
||||||
@@ -42,8 +42,8 @@ export function CompetitionCard({
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<CardContent className="p-4">
|
<CardContent className="p-4 flex-1 flex flex-col">
|
||||||
<div className="flex flex-col gap-2.5">
|
<div className="flex flex-col gap-2.5 h-full">
|
||||||
<div className="text-muted-foreground flex items-center gap-2 *:text-sm *:font-semibold">
|
<div className="text-muted-foreground flex items-center gap-2 *:text-sm *:font-semibold">
|
||||||
<span>
|
<span>
|
||||||
{competition.type === CompetitionType.COMPETITIVE
|
{competition.type === CompetitionType.COMPETITIVE
|
||||||
@@ -67,7 +67,7 @@ export function CompetitionCard({
|
|||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{competition.type === CompetitionType.COMPETITIVE && (
|
{competition.type === CompetitionType.COMPETITIVE && (
|
||||||
<div className="text-gray-500 text-sm mt-1">
|
<div className="text-gray-500 text-sm mt-auto pt-2">
|
||||||
{competition.start_date && (
|
{competition.start_date && (
|
||||||
<div className="flex items-center gap-1.5">
|
<div className="flex items-center gap-1.5">
|
||||||
<Clock size={14} />
|
<Clock size={14} />
|
||||||
|
|||||||
Reference in New Issue
Block a user