Skip to content

Commit

Permalink
Enhanced Game Server Management and Notification System Updates (#68)
Browse files Browse the repository at this point in the history
* Feature/game servers (#58)

* Add game server management functionality

This commit introduces the ability to add and delete game servers. It also includes the UI for managing game servers, validation schemas for server attributes, and relevant hooks for server data fetching and manipulation. A skeleton UI component for when server data is loading has also been included.

* Добавлено состояние отключения профиля и обновлён интерфейс серверной карты

В перечисление ProfileState добавлено состояние отключённого профиля. В файле ServerCard добавлено отображение состояний онлайн/офлайн и прогресса загрузки. Также обновлён визуальный стиль карточки сервера.

* Add profile parameter to server deletion process

The GameServerCard and DeleteGameServerDialog components have been updated to now require a profile parameter. The deletion process has been adjusted to now consider this new profile data. This change necessitates some dependency imports updates and refactoring in related files as well.

* Рефакторинг

* Исправление ошибок UX/DX и рефаторинг запросов (#61)

* Исправление ошибок UX

* Исправление ошибок DX

* Рефаторинг запросов

* Рефаторинг запросов

---------

Co-authored-by: vaterentev <vaterentev@icloud.com>

* Add notifications feature and related UI components (#62)

* Add notifications feature

Several new files and modifications have been introduced to set up the notifications feature. This includes the creation of notification services, schemas, and requests, as well as modifying the main layout to include notifications. The notifications view and UI were established and a connection hub for notifications was formed.

* Update notification hooks and display

The `useNotifications` hook was updated for a better handling of notifications data. Notification display was also refined in `NotificationPage` and `Notifications` components to cater to the changes. Additionally, some minor UI adjustments and improvements in labelling were made within various files.

* Рефакторинг

* Выбор билда клиента  (#60)

* Rebase

* Рефакторинг

* Рефакторинг

* Рефакторинг

* Рефакторинг

* Исправление недочётов в уведомлениях

* Рефакторинг

* Рефакторинг

* Орфография и рефакторинг

* Рефакторинг

* Добавлена поддержка GameLoaderOption.FABRIC в CreateProfileForm (#63)

Была расширена логика формы создания профиля для поддержки нового варианта загрузчика игры - GameLoaderOption.FABRIC. Теперь при выборе этого варианта, также активируются соответствующие поля и параметры формы.

* Обновлен интерфейс уведомлений (#65)

Были добавлены новые компоненты в интерфейс уведомлений и улучшен внешний вид уведомлений. Также увеличено количество отображаемых уведомлений с 3 до 10. Добавлен переход на страницу уведомлений при нажатии на каждое из них.

* Fix integration edit texture service (#67)

Пофиксил баг с изменением скинов и плащей

---------

Co-authored-by: Vadim Terentev <scondic@icloud.com>
Co-authored-by: vaterentev <vaterentev@icloud.com>
Co-authored-by: Akemiko <67152382+Arsenii1109@users.noreply.github.com>
  • Loading branch information
4 people authored Jul 13, 2024
1 parent 6cdd2b3 commit 92e83f9
Show file tree
Hide file tree
Showing 76 changed files with 3,899 additions and 1,469 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
# misc
.DS_Store
*.pem
.idea

# debug
npm-debug.log*
Expand Down
3,303 changes: 2,188 additions & 1,115 deletions package-lock.json

Large diffs are not rendered by default.

93 changes: 47 additions & 46 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,74 +9,75 @@
"lint": "next lint"
},
"dependencies": {
"@hookform/resolvers": "^3.3.4",
"@microsoft/signalr": "^8.0.0",
"@radix-ui/react-alert-dialog": "^1.0.5",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-dropdown-menu": "^2.0.6",
"@hookform/resolvers": "^3.9.0",
"@microsoft/signalr": "^8.0.7",
"@radix-ui/react-alert-dialog": "^1.1.1",
"@radix-ui/react-checkbox": "^1.1.1",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-dropdown-menu": "^2.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-menubar": "^1.0.4",
"@radix-ui/react-navigation-menu": "^1.1.4",
"@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-progress": "^1.0.3",
"@radix-ui/react-scroll-area": "^1.0.5",
"@radix-ui/react-select": "^2.0.0",
"@radix-ui/react-separator": "^1.0.3",
"@radix-ui/react-slot": "^1.0.2",
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tabs": "^1.0.4",
"@radix-ui/react-toast": "^1.1.5",
"@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/react-query": "^5.21.7",
"@tanstack/react-query-devtools": "^5.26.3",
"@tanstack/react-table": "^8.11.8",
"axios": "^1.6.7",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-menubar": "^1.1.1",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-popover": "^1.1.1",
"@radix-ui/react-progress": "^1.1.0",
"@radix-ui/react-scroll-area": "^1.1.0",
"@radix-ui/react-select": "^2.1.1",
"@radix-ui/react-separator": "^1.1.0",
"@radix-ui/react-slot": "^1.1.0",
"@radix-ui/react-switch": "^1.1.0",
"@radix-ui/react-tabs": "^1.1.0",
"@radix-ui/react-toast": "^1.2.1",
"@radix-ui/react-tooltip": "^1.1.2",
"@tanstack/react-query": "^5.50.1",
"@tanstack/react-query-devtools": "^5.50.1",
"@tanstack/react-table": "^8.19.2",
"axios": "^1.7.2",
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.0",
"clsx": "^2.1.1",
"cmdk": "^1.0.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.323.0",
"next": "14.1.0",
"next-themes": "^0.2.1",
"lucide-react": "^0.407.0",
"next": "14.2.5",
"next-themes": "^0.3.0",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.50.1",
"react-resizable-panels": "^2.0.4",
"sharp": "^0.33.3",
"tailwind-merge": "^2.2.1",
"react-hook-form": "^7.52.1",
"react-resizable-panels": "^2.0.20",
"sharp": "^0.33.4",
"sonner": "^1.5.0",
"tailwind-merge": "^2.4.0",
"tailwindcss-animate": "^1.0.7",
"vaul": "^0.9.0",
"zod": "^3.22.4"
"vaul": "^0.9.1",
"zod": "^3.23.8"
},
"devDependencies": {
"@feature-sliced/eslint-config": "^0.1.0-beta.6",
"@playwright/test": "^1.44.0",
"@feature-sliced/eslint-config": "^0.1.1",
"@playwright/test": "^1.45.1",
"@types/js-cookie": "^3.0.6",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"@typescript-eslint/eslint-plugin": "^6.21.0",
"@typescript-eslint/parser": "^6.21.0",
"autoprefixer": "^10.0.1",
"autoprefixer": "^10.4.19",
"eslint": "^8.57.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "14.1.0",
"eslint-config-next": "14.2.5",
"eslint-config-prettier": "^9.1.0",
"eslint-config-react-app": "^7.0.1",
"eslint-config-standard-with-typescript": "^43.0.1",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-boundaries": "^4.2.0",
"eslint-plugin-jest": "^27.6.3",
"eslint-plugin-jsx-a11y": "^6.8.0",
"eslint-plugin-boundaries": "^4.2.2",
"eslint-plugin-jest": "^27.9.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-n": "^16.6.2",
"eslint-plugin-promise": "^6.1.1",
"eslint-plugin-react": "^7.34.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-promise": "^6.4.0",
"eslint-plugin-react": "^7.34.3",
"eslint-plugin-react-hooks": "^4.6.2",
"postcss": "^8",
"prettier": "3.2.5",
"tailwindcss": "^3.3.0",
"typescript": "^5.4.2"
"prettier": "3.3.2",
"tailwindcss": "^3.4.4",
"typescript": "^5.5.3"
}
}
4 changes: 3 additions & 1 deletion src/app/dashboard/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import Image from "next/image";

import { ArrowUpDownIcon, BlocksIcon, SettingsIcon } from "lucide-react";

import { config } from "@/core/configs";

import { ChangeTheme } from "@/features/change-theme";
import { Notifications } from "@/features/notifications";

Expand Down Expand Up @@ -43,7 +45,7 @@ export default function Page({ children }: React.PropsWithChildren) {
<div className={classes["aside__wrapper-logo"]}>
<Link href="/" className={classes.aside__logo}>
<Image src={logo} alt="GML Frontend" />
GML Frontend
{config.name}
</Link>
</div>
<DesktopNavigation menu={menu} />
Expand Down
13 changes: 13 additions & 0 deletions src/app/dashboard/notification/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import type { Metadata } from "next";

import { NotificationPage } from "@/views/notification";

export const metadata: Metadata = {
title: "Уведомления",
};

const Page = () => {
return <NotificationPage />;
};

export default Page;
2 changes: 1 addition & 1 deletion src/app/dashboard/styles.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
}

.aside {
@apply hidden border-r bg-muted/40 md:block;
@apply max-h-[100vh] sticky top-0 bottom-0 hidden border-r bg-muted/40 md:block;
}

.aside__wrapper {
Expand Down
13 changes: 9 additions & 4 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,25 @@ import type { Metadata } from "next";

import { Manrope } from "next/font/google";

import "./globals.css";
import { config } from "@/core/configs";
import { QueryProvider } from "@/core/providers/QueryProvider";
import { ThemeProvider } from "@/core/providers/ThemeProvider";
import { TooltipProvider } from "@/core/providers/TooltipProvider";

import { cn } from "@/shared/lib/utils";
import { Toaster } from "@/shared/ui/toaster";
import { Toaster as Sonner } from "@/shared/ui/sonner";

import "./globals.css";

const manrope = Manrope({
subsets: ["latin"],
variable: "--font-sans",
});

export const metadata: Metadata = {
title: "GML Frontend",
description: "Официальный сайт GML",
title: config.name,
description: `Официальный сайт ${config.name}`,
};

export default function RootLayout({
Expand All @@ -25,7 +29,7 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="en">
<html lang="en" suppressHydrationWarning>
<body className={cn("min-h-screen bg-background font-sans antialiased", manrope.variable)}>
<QueryProvider>
<ThemeProvider
Expand All @@ -37,6 +41,7 @@ export default function RootLayout({
<TooltipProvider>{children}</TooltipProvider>
</ThemeProvider>
<Toaster />
<Sonner position="top-right" />
</QueryProvider>
</body>
</html>
Expand Down
4 changes: 3 additions & 1 deletion src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import Image from "next/image";
import Link from "next/link";

import { config } from "@/core/configs";

import { cn } from "@/shared/lib/utils";
import { AUTH_PAGES } from "@/shared/routes";
import { buttonVariants } from "@/shared/ui/button";
Expand All @@ -13,7 +15,7 @@ export default function Home() {
<div className="flex relative w-screen h-screen flex-col items-center justify-center gap-y-4">
<Link href="/" className="flex items-center gap-x-2 text-2xl font-bold">
<Image src={logo} alt="GML Frontend" className="w-10" />
GML Frontend
{config.name}
</Link>
<h1 className="text-xl text-center text-gray-400">
Добро пожаловать в панель <br /> управления вашим игровым проектом
Expand Down
11 changes: 11 additions & 0 deletions src/core/configs/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const BRAND_NAME = "GML";
export const PLATFORM_SHORT_APP_NAME = "Frontend";
export const PLATFORM_APP_NAME = `${BRAND_NAME} ${PLATFORM_SHORT_APP_NAME}`;

type Config = {
name: string;
};

export const config: Config = {
name: PLATFORM_APP_NAME,
};
1 change: 1 addition & 0 deletions src/entities/NotificationCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ui/NotificationCard";
41 changes: 41 additions & 0 deletions src/entities/NotificationCard/ui/NotificationCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { Copy } from "lucide-react";
import { toast as sonner } from "sonner";

import { getFormatDate } from "@/shared/lib/utils";
import { Card } from "@/shared/ui/card";
import { Button } from "@/shared/ui/button";
import { NotificationBaseEntity } from "@/shared/api/contracts";

interface ProfileCardParams {
card: NotificationBaseEntity;
}

export const NotificationCard = ({ card }: ProfileCardParams) => {
return (
<Card className={"flex flex-col justify-between gap-y-2 p-3"}>
<div className="flex justify-between items-center gap-x-2">
<span className="text-base font-semibold">{card.message}</span>
<span className="text-sm text-muted-foreground">{getFormatDate(card.date)}</span>
</div>
{card.details && (
<div className="max-h-20 overflow-hidden">
<span className="text-sm text-muted-foreground ">{card.details}</span>
</div>
)}
<Button
variant="secondary"
className="w-fit"
onClick={async () => {
await navigator.clipboard.writeText(card.details ? card.details : card.message);
sonner("Текст успешно скопирован", {
duration: 1500,
onAutoClose: () => true,
});
}}
>
<Copy className="h-3 w-3 mr-1" />
Копировать
</Button>
</Card>
);
};
5 changes: 0 additions & 5 deletions src/entities/ProfileCard/ui/ProfileCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import React from "react";

import Image from "next/image";
import { useRouter } from "next/navigation";

import { useTheme } from "next-themes";
import { Edit2Icon } from "lucide-react";
Expand All @@ -13,7 +10,6 @@ import { ClientState } from "@/widgets/client-hub";
import { InputFile } from "@/shared/ui/input";
import { Form, FormMessage } from "@/shared/ui/form";
import { useEditProfile } from "@/shared/hooks";
import { DASHBOARD_PAGES } from "@/shared/routes";

import {
EditImageProfileSchema,
Expand Down Expand Up @@ -41,7 +37,6 @@ interface ProfileCardParams {
}

export const ProfileCard = ({ profile }: ProfileCardParams) => {
const router = useRouter();
const { theme } = useTheme();

const { mutateAsync, isPending } = useEditProfile();
Expand Down
1 change: 1 addition & 0 deletions src/entities/ServerCard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ui/GameServerCard";
65 changes: 65 additions & 0 deletions src/entities/ServerCard/ui/GameServerCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import React from "react";

import Image from "next/image";

import { ClientState } from "@/widgets/client-hub";

import { DeleteGameServerDialog } from "@/features/delete-game-server";

import { GameServerBaseEntity } from "@/shared/api/contracts";
import { Card } from "@/shared/ui/card";
import { Progress } from "@/shared/ui/progress";
import { getProgressColor } from "@/shared/lib/utils";
import { EntityState } from "@/shared/enums";

import minecraftLogo from "@/assets/logos/minecraft.png";

interface GameServerCardParams {
profileName: string;
server: GameServerBaseEntity;
}

export const GameServerCard = ({ server, profileName }: GameServerCardParams) => {
const progressValue = (server.online * 100) / server.maxOnline;

return (
<Card className="flex flex-row items-center justify-between gap-y-4 p-3 pr-8">
<div className="flex flex-row gap-x-5 items-center">
<Image src={minecraftLogo} className="w-16" alt="GML Frontend" />
<div className="flex flex-col min-w-[350px]">
<span className="text-lg font-bold">{server.name}</span>
<span className="text-gray-600 dark:text-gray-400 font-medium text-sm">
{server.version ?? "Нет информации"}
</span>
</div>
{server.isOnline && (
<div>
<div className="flex flex-row items-center justify-between gap-x-3 ml-3 relative">
<Progress
value={progressValue}
className={`absolute w-full h-1 bottom-0 rounded ${getProgressColor(progressValue)}`}
/>
<div className="flex flex-row items-center justify-between gap-x-3 relative z-2 mb-3">
<div className="flex items-center justify-center text-sm font-medium text-muted-foreground rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition h-10 w-10">
{server.online}
</div>
из
<div className="flex items-center justify-center text-sm font-medium text-muted-foreground rounded-md border border-input bg-background hover:bg-accent hover:text-accent-foreground transition h-10 w-10">
{server.maxOnline}
</div>
</div>
</div>
</div>
)}
</div>
<div className="flex items-center gap-x-8">
{server.isOnline ? (
<ClientState state={EntityState.ENTITY_STATE_ACTIVE} />
) : (
<ClientState state={EntityState.ENTITY_STATE_DISABLED} />
)}
<DeleteGameServerDialog serverName={server.name} profileName={profileName} />
</div>
</Card>
);
};
Empty file.
Loading

0 comments on commit 92e83f9

Please sign in to comment.