Complete game page and add how_to_download page

This commit is contained in:
2024-05-12 20:06:41 +04:00
parent 15247adfa3
commit ab6eca4661
14 changed files with 410 additions and 267 deletions

View File

@@ -1,48 +1,126 @@
import { GameService } from "@/entities/game";
import { GameCard } from "@/features/gameCard";
import { Section } from "@/widgets/section";
import clsx from "clsx";
import Image from "next/image";
import Link from "next/link";
export default async function Games({
params: { game_id },
params: { game_id },
}: {
params: { game_id: number };
params: { game_id: number };
}) {
const gameCards = await GameService.getGameCards();
const game = await GameService.getGame(game_id);
return (
<>
{game && (
<div className="p-4 flex flex-col lp:flex-row">
{game.cover && (
<Image
src={game.cover}
className="rounded-lg w-[60%] aspect-video object-cover"
alt=""
width={1280}
height={720}
/>
)}
<div className="pt-2 max-w-[40%]">
<h1 className="text-4xl">{game.title}</h1>
<p className="text-md text-justify text-fg4 pt-2">
{game.description}
</p>
</div>
</div>
)}
const gameCards = await GameService.getGameCards();
const game = await GameService.getGame(game_id);
return (
<>
{game && (
<div className="p-4 flex flex-col lp:block">
{game.cover && (
<div className="lp:w-[60%] lp:px-4 lp:pl-0 pt-2 float-left">
<Image
src={game.cover}
className="rounded-lg aspect-video object-cover"
alt=""
width={1280}
height={720}
/>
</div>
)}
<span className="pt-2 lp:max-w-[40%]">
<h1 className="text-4xl">{game.title}</h1>
{game.description && (
<p className="text-md text-justify text-fg4 pt-2">
{game.description}
</p>
)}
</span>
<div className="flex justify-between pt-6">
{[
[
{ name: "Система", value: game.system },
{ name: "Процессор", value: game.processor },
{ name: "Оперативная память", value: game.memory },
{ name: "Видеокарта", value: game.graphics },
{ name: "Место на диске", value: game.storage },
],
[
{
name: "Версия игры",
value: `${
game.version
} (обновлена ${game.update_date.toLocaleDateString(
"ru-ru"
)})`,
},
{ name: "Язык", value: game.language },
{ name: "Разработчик", value: game.developer },
{
name: "Год выхода",
value: game.release_date.toLocaleDateString("en-us", {
year: "numeric",
}),
},
{ name: "Объём загрузки", value: game.download_size },
],
].map((section, i) => (
<ul key={i} className="w-[48%] bg-bg1 rounded-lg py-1 px-4">
{section.map((req) => (
<li
key={req.name}
className="font-bold text-sm lp:text-md py-1"
>
{req.name + ": "}
<span
className={clsx(
"font-normal",
req.value === undefined && "text-fg4"
)}
>
{req.value ?? "Не известно"}
</span>
</li>
))}
</ul>
))}
</div>
{game.trailer && (
<iframe
src={game.trailer.replace("/watch?v=", "/embed/")}
className="w-full aspect-video rounded-lg my-4"
allowFullScreen
/>
)}
<div className="relative w-full flex items-center justify-around">
<Link
href={
process.env.NEXT_PUBLIC_CONTENT_URL + "/" + game.torrent_file
}
className="p-4 bg-ac0 text-fg1 text-xl rounded-lg"
>
Скачать {game.title}.torrent
</Link>
</div>
<div className="w-full flex justify-end">
<Link className="text-right text-sm" href="/how_to_download">
Как скачать игру
<br /> с помощью .torrent файла?
</Link>
</div>
</div>
)}
{gameCards && (
<Section
name="Другие популярные игры"
link="/games"
invite_text={'Перейти в раздел "Игры"'}
>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
{gameCards && (
<Section
name="Другие популярные игры"
link="/games"
invite_text={'Перейти в раздел "Игры"'}
>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
}

View File

@@ -4,22 +4,22 @@ import { Section } from "@/widgets/section";
import { Metadata } from "next";
export const metadata: Metadata = {
title: ".Torrent: Игры",
description:
".Torrent: Игры - каталог .torrent файлов для обмена видеоиграми",
title: ".Torrent: Игры",
description:
".Torrent: Игры - каталог .torrent файлов для обмена видеоиграми",
};
export default async function Games() {
const gameCards = await GameService.getGameCards();
return (
<>
{gameCards && (
<Section>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
const gameCards = await GameService.getGameCards();
return (
<>
{gameCards && gameCards.length > 0 && (
<Section>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
}

View File

@@ -11,8 +11,12 @@
--color-fg1: #3c3836;
--color-fg4: #7c6f64;
--color-ac0: #83a598;
--color-ac1: #fabd2f;
--color-ac2: #8ec07c;
--app-width: 70%;
font-size: calc((100vh / 1080) * 24);
font-size: calc((100vw / 1920) * 24);
}
[data-theme="dark"] {
@@ -23,6 +27,10 @@
--color-fg0: #fbf1c7;
--color-fg1: #ebdbb2;
--color-fg4: #a89984;
--color-ac0: #076678;
--color-ac1: #b57614;
--color-ac2: #427b58;
}
html,
@@ -37,7 +45,7 @@ body {
transition-property: color, background-color, border-color;
transition-duration: 0.3s;
overflow: hidden;
/* overflow: hidden; */
color: var(--color-fg1);
background-color: var(--color-bg0);
}
@@ -48,8 +56,13 @@ body {
}
}
@media (max-width: 1024px) {
:root {
font-size: calc((100vw / 1920) * 56);
}
}
@media (max-width: 640px) {
:root {
font-size: calc((100vh / 1080) * 16);
font-size: calc((100vw / 1920) * 64);
}
}
}

View File

@@ -0,0 +1,61 @@
import { Metadata } from "next";
export const metadata: Metadata = {
title: ".Torrent: Как скачать?",
description:
".Torrent: Как скачать? - краткое руководство по скачиваю данных с помощью .torrent файлов",
};
export default async function HowToDownload() {
return (
<div className="w-full flex flex-col lp:flex-row justify-between p-4">
<div className="w-full p-4 lp:w-[50%] lp:pr-10">
<h1 className="text-4xl lp:text-3xl">Как скачать?</h1>
<div className="text-fg4 text-justify pt-2">
Чтобы скачать что-либо с помощью торрент-файла, выполните следующие
шаги:
<ul className="*:text-fg4">
<li>
1. Найдите и загрузите торрент-файл или magnet-ссылку, содержащую
информацию о файле, который вы хотите скачать.
</li>
<li>
2. Откройте программу-клиент для загрузки торрентов, например,
uTorrent, BitTorrent или qBittorrent.
</li>
<li>
3. В программе-клиенте выберите опцию "Open Torrent File" или "Add
Torrent" и выберите торрент-файл, который вы скачали в первом
шаге.
</li>
<li>
4. После этого начнется загрузка файлов, указанных в
торрент-файле. Вы также можете выбрать папку, куда сохранять
скачанные файлы.
</li>
<li>
5. Дождитесь завершения загрузки файлов. После этого вы сможете
открыть и использовать скачанные файлы на своем компьютере.
</li>
</ul>
</div>
</div>
<div className="w-full p-4 lp:w-[50%] lp:pl-10">
<h2 className="text-4xl lp:text-3xl">Что такое .torrent файл?</h2>
<p className="text-fg4 text-justify pt-2">
Торрент-файл (или .torrent-файл) - это небольшой файл, который
содержит метаданные о файле или наборе файлов, которые можно загрузить
с помощью протокола BitTorrent. В торрент-файле обычно указан адрес
трекера (специального сервера, отслеживающего пиров) и хеш-суммы
частей файлов, которые необходимы для скачивания.
<br />
<br /> Пользователь, желающий загрузить файл через BitTorrent, сначала
скачивает торрент-файл или magnet-ссылку, загружает ее в
торрент-клиент (программу для скачивания торрентов), и затем начинает
загрузку файлов, участвуя в обмене данными с другими пользователями
(пирами) через сеть BitTorrent.
</p>
</div>
</div>
);
}

View File

@@ -7,27 +7,27 @@ import { Header } from "@/widgets/header";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: ".Torrent",
description:
".Torrent - сервис обмена .torrent файлами видеоигр, фильмов и аудиокниг",
title: ".Torrent",
description:
".Torrent - сервис обмена .torrent файлами видеоигр, фильмов и аудиокниг",
};
export default function RootLayout({
children,
children,
}: Readonly<{
children: React.ReactNode;
children: React.ReactNode;
}>) {
return (
// suppressHydrationWarning for theme support
<html lang="ru" suppressHydrationWarning>
<body className={inter.className}>
<ThemeProvider enableSystem={false} defaultTheme="light">
<Header />
<div className="w-full h-full max-w-[var(--app-width)] m-auto overflow-y-auto">
{children}
</div>
</ThemeProvider>
</body>
</html>
);
return (
// suppressHydrationWarning for theme support
<html lang="ru" suppressHydrationWarning>
<body className={inter.className}>
<ThemeProvider enableSystem={false} defaultTheme="light">
<Header />
<div className="w-full h-full max-w-[var(--app-width)] m-auto">
{children}
</div>
</ThemeProvider>
</body>
</html>
);
}

View File

@@ -3,20 +3,20 @@ import { GameCard } from "@/features/gameCard";
import { Section } from "@/widgets/section";
export default async function Home() {
const gameCards = await GameService.getGameCards();
return (
<>
{gameCards && (
<Section
name="Игры"
link="/games"
invite_text={'Перейти в раздел "Игры"'}
>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
const gameCards = await GameService.getGameCards();
return (
<>
{gameCards && gameCards.length > 0 && (
<Section
name="Игры"
link="/games"
invite_text={'Перейти в раздел "Игры"'}
>
{gameCards.map((card) => (
<GameCard key={card.id} card={card} />
))}
</Section>
)}
</>
);
}