dev #1
@@ -7,6 +7,7 @@ import { useAppDispatch, useAppSelector } from "../redux/hooks";
|
|||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { fetchWhoAmI } from "../redux/slices/auth";
|
import { fetchWhoAmI } from "../redux/slices/auth";
|
||||||
import Problems from "../views/home/problems/Problems";
|
import Problems from "../views/home/problems/Problems";
|
||||||
|
import Articles from "../views/home/articles/Articles";
|
||||||
|
|
||||||
const Home = () => {
|
const Home = () => {
|
||||||
const name = useAppSelector((state) => state.auth.username);
|
const name = useAppSelector((state) => state.auth.username);
|
||||||
@@ -19,7 +20,7 @@ const Home = () => {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full bg-liquid-background grid grid-cols-[250px,1fr] divide-x-[1px] divide-liquid-lighter">
|
<div className="w-full bg-liquid-background grid grid-cols-[250px,1fr,250px] divide-x-[1px] divide-liquid-lighter">
|
||||||
<div className="min-h-screen">
|
<div className="min-h-screen">
|
||||||
<Menu />
|
<Menu />
|
||||||
</div>
|
</div>
|
||||||
@@ -29,10 +30,15 @@ const Home = () => {
|
|||||||
<Route path="account" element={<Login />} />
|
<Route path="account" element={<Login />} />
|
||||||
<Route path="register" element={<Register />} />
|
<Route path="register" element={<Register />} />
|
||||||
<Route path="problems/*" element={<Problems/>} />
|
<Route path="problems/*" element={<Problems/>} />
|
||||||
|
<Route path="articles/*" element={<Articles/>} />
|
||||||
<Route path="*" element={name} />
|
<Route path="*" element={name} />
|
||||||
</Routes>
|
</Routes>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
{
|
||||||
|
<Routes>
|
||||||
|
<Route path="articles/*" element={<div></div>} />
|
||||||
|
</Routes>
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
50
src/views/home/articles/ArticleItem.tsx
Normal file
50
src/views/home/articles/ArticleItem.tsx
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import { Logo } from "../../../assets/logos";
|
||||||
|
import { Account, Clipboard, Cup, Home, Openbook, Users } from "../../../assets/icons/menu";
|
||||||
|
// import MenuItem from "./MenuItem";
|
||||||
|
import { cn } from "../../../lib/cn";
|
||||||
|
import { IconError, IconSuccess } from "../../../assets/icons/problems";
|
||||||
|
|
||||||
|
export interface ArticleItemProps {
|
||||||
|
id: number;
|
||||||
|
authorId: number;
|
||||||
|
name: string;
|
||||||
|
tags: string[];
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function formatMilliseconds(ms: number): string {
|
||||||
|
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 ArticleItem: React.FC<ArticleItemProps> = ({
|
||||||
|
id, authorId, name, tags, createdAt, updatedAt
|
||||||
|
}) => {
|
||||||
|
console.log(id);
|
||||||
|
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-[1fr,1fr,1fr] grid-flow-col gap-[20px] px-[20px] box-border items-center",
|
||||||
|
)}>
|
||||||
|
<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)} */}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ArticleItem;
|
||||||
107
src/views/home/articles/Articles.tsx
Normal file
107
src/views/home/articles/Articles.tsx
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
import { Logo } from "../../../assets/logos";
|
||||||
|
import { Account, Clipboard, Cup, Home, Openbook, Users } from "../../../assets/icons/menu";
|
||||||
|
// import MenuItem from "./MenuItem";
|
||||||
|
import { useAppSelector } from "../../../redux/hooks";
|
||||||
|
// import ProblemItem from "./ProblemItem";
|
||||||
|
import { SecondaryButton } from "../../../components/button/SecondaryButton";
|
||||||
|
|
||||||
|
|
||||||
|
export interface Problem {
|
||||||
|
id: number;
|
||||||
|
authorId: number;
|
||||||
|
name: string;
|
||||||
|
difficulty: "Easy" | "Medium" | "Hard";
|
||||||
|
tags: string[];
|
||||||
|
timeLimit: number;
|
||||||
|
memoryLimit: number;
|
||||||
|
createdAt: string;
|
||||||
|
updatedAt: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Articles = () => {
|
||||||
|
|
||||||
|
const problems: Problem[] = [
|
||||||
|
{
|
||||||
|
"id": 1,
|
||||||
|
"authorId": 1,
|
||||||
|
"name": "Todo List App",
|
||||||
|
"difficulty": "Easy",
|
||||||
|
"tags": ["react", "state", "list"],
|
||||||
|
"timeLimit": 1000,
|
||||||
|
"memoryLimit": 268435456,
|
||||||
|
"createdAt": "2025-10-28T13:23:13.000Z",
|
||||||
|
"updatedAt": "2025-10-28T13:23:13.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 2,
|
||||||
|
"authorId": 1,
|
||||||
|
"name": "Search Filter Component",
|
||||||
|
"difficulty": "Medium",
|
||||||
|
"tags": ["filter", "props", "hooks"],
|
||||||
|
"timeLimit": 1000,
|
||||||
|
"memoryLimit": 268435456,
|
||||||
|
"createdAt": "2025-10-28T13:23:14.000Z",
|
||||||
|
"updatedAt": "2025-10-28T13:23:14.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 3,
|
||||||
|
"authorId": 1,
|
||||||
|
"name": "User Card List",
|
||||||
|
"difficulty": "Easy",
|
||||||
|
"tags": ["components", "props", "array"],
|
||||||
|
"timeLimit": 1000,
|
||||||
|
"memoryLimit": 268435456,
|
||||||
|
"createdAt": "2025-10-28T13:23:15.000Z",
|
||||||
|
"updatedAt": "2025-10-28T13:23:15.000Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 4,
|
||||||
|
"authorId": 1,
|
||||||
|
"name": "Theme Switcher",
|
||||||
|
"difficulty": "Medium",
|
||||||
|
"tags": ["context", "theme", "hooks"],
|
||||||
|
"timeLimit": 1000,
|
||||||
|
"memoryLimit": 268435456,
|
||||||
|
"createdAt": "2025-10-28T13:23:16.000Z",
|
||||||
|
"updatedAt": "2025-10-28T13:23:16.000Z"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
|
||||||
|
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={() => {}}
|
||||||
|
text="Создать статью"
|
||||||
|
className="absolute right-0"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="bg-liquid-lighter h-[50px] mb-[20px]">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
|
||||||
|
{/* {problems.map((v, i) => (
|
||||||
|
<ProblemItem key={i} {...v} 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>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Articles;
|
||||||
@@ -7,7 +7,7 @@ const Menu = () => {
|
|||||||
const menuItems = [
|
const menuItems = [
|
||||||
{text: "Главная", href: "/home", icon: Home, page: "home" },
|
{text: "Главная", href: "/home", icon: Home, page: "home" },
|
||||||
{text: "Задачи", href: "/home/problems", icon: Clipboard, page: "clipboard" },
|
{text: "Задачи", href: "/home/problems", icon: Clipboard, page: "clipboard" },
|
||||||
{text: "Статьи", href: "/home", icon: Openbook, page: "openbool" },
|
{text: "Статьи", href: "/home/articles", icon: Openbook, page: "openbool" },
|
||||||
{text: "Группы", href: "/home", icon: Users, page: "users" },
|
{text: "Группы", href: "/home", icon: Users, page: "users" },
|
||||||
{text: "Контесты", href: "/home", icon: Cup, page: "cup" },
|
{text: "Контесты", href: "/home", icon: Cup, page: "cup" },
|
||||||
{text: "Аккаунт", href: "/home/account", icon: Account, page: "account" },
|
{text: "Аккаунт", href: "/home/account", icon: Account, page: "account" },
|
||||||
|
|||||||
@@ -466,8 +466,8 @@ const Problems = () => {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className=" h-full w-full box-border p-[20px] pt-[35px]">
|
<div className=" h-full w-full box-border p-[20px] pt-[20px]">
|
||||||
<div className="h-full box-border mr-[250px]">
|
<div className="h-full box-border">
|
||||||
|
|
||||||
<div className="relative flex items-center mb-[20px]">
|
<div className="relative flex items-center mb-[20px]">
|
||||||
<div className="h-[50px] text-[40px] font-bold text-liquid-white flex items-center">
|
<div className="h-[50px] text-[40px] font-bold text-liquid-white flex items-center">
|
||||||
|
|||||||
Reference in New Issue
Block a user