formatting

This commit is contained in:
Виталий Лавшонок
2025-11-04 15:04:59 +03:00
parent 3cd8e14288
commit 4972836164
60 changed files with 3604 additions and 2916 deletions

View File

@@ -1,71 +1,78 @@
import { cn } from "../../../lib/cn";
import { IconError, IconSuccess } from "../../../assets/icons/missions";
import { useNavigate } from "react-router-dom";
import { cn } from '../../../lib/cn';
import { IconError, IconSuccess } from '../../../assets/icons/missions';
import { useNavigate } from 'react-router-dom';
export interface MissionItemProps {
id: number;
authorId: number;
name: string;
difficulty: "Easy" | "Medium" | "Hard";
difficulty: 'Easy' | 'Medium' | 'Hard';
tags: string[];
timeLimit: number;
memoryLimit: number;
createdAt: string;
updatedAt: string;
type: "first" | "second";
status: "empty" | "success" | "error";
type: 'first' | 'second';
status: 'empty' | 'success' | 'error';
}
export function formatMilliseconds(ms: number): string {
const rounded = Math.round(ms) / 1000;
const formatted = rounded.toString().replace(/\.?0+$/, '');
return `${formatted} c`;
const rounded = Math.round(ms) / 1000;
const formatted = rounded.toString().replace(/\.?0+$/, '');
return `${formatted} c`;
}
export function formatBytesToMB(bytes: number): string {
const megabytes = Math.floor(bytes / (1024 * 1024));
return `${megabytes} МБ`;
const megabytes = Math.floor(bytes / (1024 * 1024));
return `${megabytes} МБ`;
}
const MissionItem: React.FC<MissionItemProps> = ({
id, name, difficulty, timeLimit, memoryLimit, type, status
id,
name,
difficulty,
timeLimit,
memoryLimit,
type,
status,
}) => {
const navigate = useNavigate();
return (
<div className={cn("h-[44px] w-full relative rounded-[10px] text-liquid-white",
type == "first" ? "bg-liquid-lighter" : "bg-liquid-background",
"grid grid-cols-[80px,1fr,1fr,60px,24px] grid-flow-col gap-[20px] px-[20px] box-border items-center",
status == "error" && "border-l-[11px] border-l-liquid-red pl-[9px]",
status == "success" && "border-l-[11px] border-l-liquid-green pl-[9px]",
"cursor-pointer brightness-100 hover:brightness-125 transition-all duration-300",
)}
onClick={() => {navigate(`/mission/${id}`)}}
<div
className={cn(
'h-[44px] w-full relative rounded-[10px] text-liquid-white',
type == 'first' ? 'bg-liquid-lighter' : 'bg-liquid-background',
'grid grid-cols-[80px,1fr,1fr,60px,24px] grid-flow-col gap-[20px] px-[20px] box-border items-center',
status == 'error' &&
'border-l-[11px] border-l-liquid-red pl-[9px]',
status == 'success' &&
'border-l-[11px] border-l-liquid-green pl-[9px]',
'cursor-pointer brightness-100 hover:brightness-125 transition-all duration-300',
)}
onClick={() => {
navigate(`/mission/${id}`);
}}
>
<div className="text-[18px] font-bold">
#{id}
</div>
<div className="text-[18px] font-bold">
{name}
</div>
<div className="text-[18px] font-bold">#{id}</div>
<div className="text-[18px] font-bold">{name}</div>
<div className="text-[12px] text-right">
стандартный ввод/вывод {formatMilliseconds(timeLimit)}, {formatBytesToMB(memoryLimit)}
стандартный ввод/вывод {formatMilliseconds(timeLimit)},{' '}
{formatBytesToMB(memoryLimit)}
</div>
<div className={cn(
"text-center text-[18px]",
difficulty == "Hard" && "text-liquid-red",
difficulty == "Medium" && "text-liquid-orange",
difficulty == "Easy" && "text-liquid-green",
)}>
<div
className={cn(
'text-center text-[18px]',
difficulty == 'Hard' && 'text-liquid-red',
difficulty == 'Medium' && 'text-liquid-orange',
difficulty == 'Easy' && 'text-liquid-green',
)}
>
{difficulty}
</div>
<div className="h-[24px] w-[24px]">
{
status == "error" && <img src={IconError}/>
}
{
status == "success" && <img src={IconSuccess}/>
}
{status == 'error' && <img src={IconError} />}
{status == 'success' && <img src={IconSuccess} />}
</div>
</div>
);

View File

@@ -1,18 +1,17 @@
import MissionItem from "./MissionItem";
import { SecondaryButton } from "../../../components/button/SecondaryButton";
import { useAppDispatch, useAppSelector } from "../../../redux/hooks";
import { useEffect, useState } from "react";
import { setMenuActivePage } from "../../../redux/slices/store";
import { useNavigate } from "react-router-dom";
import { fetchMissions } from "../../../redux/slices/missions";
import ModalCreate from "./ModalCreate";
import MissionItem from './MissionItem';
import { SecondaryButton } from '../../../components/button/SecondaryButton';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import { useEffect, useState } from 'react';
import { setMenuActivePage } from '../../../redux/slices/store';
import { useNavigate } from 'react-router-dom';
import { fetchMissions } from '../../../redux/slices/missions';
import ModalCreate from './ModalCreate';
export interface Mission {
id: number;
authorId: number;
name: string;
difficulty: "Easy" | "Medium" | "Hard";
difficulty: 'Easy' | 'Medium' | 'Hard';
tags: string[];
timeLimit: number;
memoryLimit: number;
@@ -21,60 +20,60 @@ export interface Mission {
}
const Missions = () => {
const dispatch = useAppDispatch();
const [modalActive, setModalActive] = useState<boolean>(false);
const missions = useAppSelector((state) => state.missions.missions);
useEffect(() => {
dispatch(setMenuActivePage("missions"))
dispatch(fetchMissions({}))
dispatch(setMenuActivePage('missions'));
dispatch(fetchMissions({}));
}, []);
return (
<div className=" h-full w-full box-border p-[20px] pt-[20px]">
<div className="h-full box-border">
<div className="relative flex items-center mb-[20px]">
<div className="h-[50px] text-[40px] font-bold text-liquid-white flex items-center">
Задачи
</div>
<SecondaryButton
onClick={() => {setModalActive(true)}}
<SecondaryButton
onClick={() => {
setModalActive(true);
}}
text="Добавить задачу"
className="absolute right-0"
/>
</div>
<div className="bg-liquid-lighter h-[50px] mb-[20px]">
</div>
<div className="bg-liquid-lighter h-[50px] mb-[20px]"></div>
<div>
{missions.map((v, i) => (
<MissionItem
key={i}
id={v.id}
authorId={v.authorId}
name={v.name}
difficulty={"Easy"}
tags={v.tags}
timeLimit={1000}
memoryLimit={256 * 1024 * 1024}
createdAt={v.createdAt}
updatedAt={v.updatedAt}
type={i % 2 == 0 ? "first" : "second"}
status={i == 0 || i == 3 || i == 7 ? "success" : (i == 2 || i == 4 || i == 9 ? "error" : "empty")}/>
))}
{missions.map((v, i) => (
<MissionItem
key={i}
id={v.id}
authorId={v.authorId}
name={v.name}
difficulty={'Easy'}
tags={v.tags}
timeLimit={1000}
memoryLimit={256 * 1024 * 1024}
createdAt={v.createdAt}
updatedAt={v.updatedAt}
type={i % 2 == 0 ? 'first' : 'second'}
status={
i == 0 || i == 3 || i == 7
? 'success'
: i == 2 || i == 4 || i == 9
? 'error'
: 'empty'
}
/>
))}
</div>
<div>
pages
</div>
<div>pages</div>
</div>
<ModalCreate setActive={setModalActive} active={modalActive} />

View File

@@ -59,6 +59,10 @@ const ModalCreate: FC<ModalCreateProps> = ({ active, setActive }) => {
}
}, [status]);
useEffect(() => {
dispatch(setMissionsStatus({ key: 'upload', status: 'idle' }));
}, [active]);
return (
<Modal
className="bg-liquid-background border-liquid-lighter border-[2px] p-[25px] rounded-[20px] text-liquid-white"
@@ -152,6 +156,8 @@ const ModalCreate: FC<ModalCreateProps> = ({ active, setActive }) => {
text="Отмена"
/>
</div>
{status == 'failed' && <div>error</div>}
</div>
</Modal>
);