mirror of
https://github.com/StepanovPlaton/torrent_frontend.git
synced 2026-04-03 12:20:48 +04:00
Refactoring
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { GameService, GameType, isSection, ItemService } from "@/entities/item";
|
||||
import { ItemCard } from "@/features/itemCard";
|
||||
import { ItemService } from "@/entities/item";
|
||||
import { SectionService } from "@/features/sections";
|
||||
import { ItemCard } from "@/widgets/itemCard";
|
||||
import { ItemInfo } from "@/widgets/itemInfo";
|
||||
import { Section } from "@/widgets/section";
|
||||
import { redirect } from "next/navigation";
|
||||
@@ -9,13 +10,17 @@ export default async function Item({
|
||||
}: {
|
||||
params: { section: string; item_id: number };
|
||||
}) {
|
||||
const game = isSection(section)
|
||||
? await ItemService.itemSections[section].service.Get(item_id)
|
||||
const game = SectionService.isSection(section)
|
||||
? await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.Get(item_id)
|
||||
: redirect("/");
|
||||
|
||||
const cards =
|
||||
isSection(section) &&
|
||||
(await ItemService.itemSections[section].service.GetCards());
|
||||
SectionService.isSection(section) &&
|
||||
(await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.GetCards());
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -24,14 +29,15 @@ export default async function Item({
|
||||
{cards && (
|
||||
<Section
|
||||
name={
|
||||
isSection(section)
|
||||
? ItemService.itemSections[section].popularSubsectionName
|
||||
SectionService.isSection(section)
|
||||
? SectionService.sectionsConfiguration[section]
|
||||
.popularSubsectionName
|
||||
: undefined
|
||||
}
|
||||
link={isSection(section) ? `/${section}` : undefined}
|
||||
link={SectionService.isSection(section) ? `/${section}` : undefined}
|
||||
invite_text={
|
||||
isSection(section)
|
||||
? ItemService.itemSections[section].sectionInviteText
|
||||
SectionService.isSection(section)
|
||||
? SectionService.sectionsConfiguration[section].sectionInviteText
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { GameService, isSection, ItemService } from "@/entities/item";
|
||||
import { ItemCard } from "@/features/itemCard";
|
||||
import { ItemCard } from "@/widgets/itemCard";
|
||||
import { ItemInfo } from "@/widgets/itemInfo";
|
||||
import { Section } from "@/widgets/section";
|
||||
import { redirect } from "next/navigation";
|
||||
import { Metadata } from "next";
|
||||
import { SectionService } from "@/features/sections";
|
||||
import { ItemService } from "@/entities/item";
|
||||
|
||||
export async function generateMetadata({
|
||||
params: { section },
|
||||
}: {
|
||||
params: { section: string };
|
||||
}): Promise<Metadata> {
|
||||
if (!isSection(section)) {
|
||||
if (!SectionService.isSection(section)) {
|
||||
redirect("/");
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
title: `.Torrent: ${ItemService.itemSections[section].addItemText}`,
|
||||
title: `.Torrent: ${SectionService.sectionsConfiguration[section].addItemText}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,13 +25,17 @@ export default async function AddItem({
|
||||
}: {
|
||||
params: { section: string };
|
||||
}) {
|
||||
const emptyItem = isSection(section)
|
||||
? await ItemService.itemSections[section].service.GetEmpty()
|
||||
const emptyItem = SectionService.isSection(section)
|
||||
? await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.GetEmpty()
|
||||
: redirect("/");
|
||||
|
||||
const cards =
|
||||
isSection(section) &&
|
||||
(await ItemService.itemSections[section].service.GetCards());
|
||||
SectionService.isSection(section) &&
|
||||
(await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.GetCards());
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -39,14 +44,15 @@ export default async function AddItem({
|
||||
{cards && (
|
||||
<Section
|
||||
name={
|
||||
isSection(section)
|
||||
? ItemService.itemSections[section].popularSubsectionName
|
||||
SectionService.isSection(section)
|
||||
? SectionService.sectionsConfiguration[section]
|
||||
.popularSubsectionName
|
||||
: undefined
|
||||
}
|
||||
link={isSection(section) ? `/${section}` : undefined}
|
||||
link={SectionService.isSection(section) ? `/${section}` : undefined}
|
||||
invite_text={
|
||||
isSection(section)
|
||||
? ItemService.itemSections[section].sectionInviteText
|
||||
SectionService.isSection(section)
|
||||
? SectionService.sectionsConfiguration[section].sectionInviteText
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
import { isSection, ItemService, MovieService } from "@/entities/item";
|
||||
import { ItemCard } from "@/features/itemCard";
|
||||
import { ItemCard } from "@/widgets/itemCard";
|
||||
import { Section } from "@/widgets/section";
|
||||
import { redirect } from "next/navigation";
|
||||
import { Metadata } from "next";
|
||||
import { SectionService } from "@/features/sections";
|
||||
|
||||
export async function generateMetadata({
|
||||
params: { section },
|
||||
}: {
|
||||
params: { section: string };
|
||||
}): Promise<Metadata> {
|
||||
if (!isSection(section)) {
|
||||
if (!SectionService.isSection(section)) {
|
||||
redirect("/");
|
||||
return {};
|
||||
}
|
||||
return {
|
||||
title: `.Torrent: ${ItemService.itemSections[section].sectionName}`,
|
||||
description: `.Torrent: ${ItemService.itemSections[section].sectionName} - ${ItemService.itemSections[section].sectionName}`,
|
||||
title: `.Torrent: ${SectionService.sectionsConfiguration[section].sectionName}`,
|
||||
description:
|
||||
`.Torrent: ` +
|
||||
`${SectionService.sectionsConfiguration[section].sectionName} - ` +
|
||||
`${SectionService.sectionsConfiguration[section].sectionDescription}`,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -24,8 +28,10 @@ export default async function SectionPage({
|
||||
}: {
|
||||
params: { section: string };
|
||||
}) {
|
||||
const cards = isSection(section)
|
||||
? await ItemService.itemSections[section].service.GetCards()
|
||||
const cards = SectionService.isSection(section)
|
||||
? await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.GetCards()
|
||||
: redirect("/");
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import {
|
||||
isSection,
|
||||
ItemCardType,
|
||||
ItemSections,
|
||||
ItemSectionsType,
|
||||
ItemService,
|
||||
} from "@/entities/item";
|
||||
import { ItemCard } from "@/features/itemCard";
|
||||
import { ItemCardType, ItemService } from "@/entities/item";
|
||||
import { ItemCard } from "@/widgets/itemCard";
|
||||
import { SectionService, SectionType } from "@/features/sections";
|
||||
import { Section } from "@/widgets/section";
|
||||
import { Metadata } from "next";
|
||||
|
||||
@@ -16,24 +11,31 @@ export const metadata: Metadata = {
|
||||
};
|
||||
|
||||
export default async function Home() {
|
||||
const cards: { [k in ItemSectionsType]?: ItemCardType[] | null } = {};
|
||||
const cards: { [k in SectionType]?: ItemCardType[] | null } = {};
|
||||
await Promise.all(
|
||||
ItemSections.map(async (section) => {
|
||||
cards[section] = await ItemService.itemSections[
|
||||
section
|
||||
SectionService.sections.map(async (section) => {
|
||||
cards[section] = await ItemService.itemsConfiguration[
|
||||
SectionService.sectionsConfiguration[section].itemType
|
||||
].service.GetCards();
|
||||
})
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
{ItemSections.map((section) => (
|
||||
{SectionService.sections.map((section) => (
|
||||
<section key={section}>
|
||||
{cards[section] && cards[section].length > 0 && (
|
||||
<Section
|
||||
name={ItemService.itemSections[section].popularSubsectionName}
|
||||
link={isSection(section) ? `/${section}` : undefined}
|
||||
invite_text={ItemService.itemSections[section].sectionInviteText}
|
||||
name={
|
||||
SectionService.sectionsConfiguration[section]
|
||||
.popularSubsectionName
|
||||
}
|
||||
link={
|
||||
SectionService.isSection(section) ? `/${section}` : undefined
|
||||
}
|
||||
invite_text={
|
||||
SectionService.sectionsConfiguration[section].sectionInviteText
|
||||
}
|
||||
>
|
||||
{cards[section].map((card) => (
|
||||
<ItemCard key={card.id} card={card} />
|
||||
|
||||
@@ -85,20 +85,16 @@ import { ItemService } from "./item";
|
||||
export { ItemService };
|
||||
|
||||
import {
|
||||
isSection,
|
||||
TypesOfItems,
|
||||
type IItemService,
|
||||
type ItemType,
|
||||
type ItemCardType,
|
||||
type ItemCreateType,
|
||||
type TypesOfItems,
|
||||
type ItemSectionsType,
|
||||
ItemSections,
|
||||
} from "./types";
|
||||
export {
|
||||
isSection,
|
||||
TypesOfItems,
|
||||
type IItemService,
|
||||
type ItemType,
|
||||
type ItemCardType,
|
||||
type ItemCreateType,
|
||||
type TypesOfItems,
|
||||
type ItemSectionsType,
|
||||
ItemSections,
|
||||
};
|
||||
|
||||
@@ -7,10 +7,8 @@ import { audiobookCreateSchema } from "./audiobook/schemas/audiobook";
|
||||
import { AudiobookService } from "./audiobook/audiobook";
|
||||
import {
|
||||
IItemService,
|
||||
ItemCardType,
|
||||
ItemCreateType,
|
||||
ItemPropertiesDescriptionType,
|
||||
ItemSectionsType,
|
||||
ItemType,
|
||||
TypesOfItems,
|
||||
UnionItemType,
|
||||
@@ -18,9 +16,8 @@ import {
|
||||
import { EraseCacheByTags } from "@/shared/utils/http";
|
||||
|
||||
export abstract class ItemService {
|
||||
private static get itemsConfiguration(): {
|
||||
static get itemsConfiguration(): {
|
||||
[k in TypesOfItems]: {
|
||||
sectionUrl: ItemSectionsType;
|
||||
formResolver: ZodSchema;
|
||||
propertiesDescription: ItemPropertiesDescriptionType<UnionItemType>;
|
||||
service: IItemService;
|
||||
@@ -28,19 +25,16 @@ export abstract class ItemService {
|
||||
} {
|
||||
return {
|
||||
[TypesOfItems.game]: {
|
||||
sectionUrl: "games",
|
||||
formResolver: gameCreateSchema,
|
||||
propertiesDescription: GameService.propertiesDescription,
|
||||
service: GameService,
|
||||
},
|
||||
[TypesOfItems.movie]: {
|
||||
sectionUrl: "movies",
|
||||
formResolver: movieCreateSchema,
|
||||
propertiesDescription: MovieService.propertiesDescription,
|
||||
service: MovieService,
|
||||
},
|
||||
[TypesOfItems.audiobook]: {
|
||||
sectionUrl: "audiobooks",
|
||||
formResolver: audiobookCreateSchema,
|
||||
propertiesDescription: AudiobookService.propertiesDescription,
|
||||
service: AudiobookService,
|
||||
@@ -48,76 +42,12 @@ export abstract class ItemService {
|
||||
};
|
||||
}
|
||||
|
||||
static get itemSections(): {
|
||||
[k in ItemSectionsType]: {
|
||||
sectionName: string;
|
||||
itemType: TypesOfItems;
|
||||
popularSubsectionName: string;
|
||||
sectionInviteText: string;
|
||||
addItemText: string;
|
||||
sectionDescription: string;
|
||||
service: IItemService;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
games: {
|
||||
sectionName: "Игры",
|
||||
itemType: TypesOfItems.game,
|
||||
popularSubsectionName: "Популярные игры",
|
||||
sectionInviteText: 'Перейти в раздел "Игры"',
|
||||
addItemText: "Добавить игру",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена актуальными версиями популярных игр",
|
||||
service: GameService,
|
||||
},
|
||||
movies: {
|
||||
sectionName: "Фильмы",
|
||||
itemType: TypesOfItems.movie,
|
||||
popularSubsectionName: "Популярные фильмы",
|
||||
sectionInviteText: 'Перейти в раздел "Фильмы"',
|
||||
addItemText: "Добавить фильм",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена популярными фильмами в лучшем качестве",
|
||||
service: MovieService,
|
||||
},
|
||||
audiobooks: {
|
||||
sectionName: "Аудиокниги",
|
||||
itemType: TypesOfItems.audiobook,
|
||||
popularSubsectionName: "Популярные аудиокниги",
|
||||
sectionInviteText: 'Перейти в раздел "Аудиокниги"',
|
||||
addItemText: "Добавить аудиокнигу",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена популярными аудиокнигами любимых авторов",
|
||||
service: AudiobookService,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public static isExistingItem(
|
||||
item: ItemCreateType | ItemType
|
||||
): item is ItemType {
|
||||
return (item as ItemType).id !== undefined;
|
||||
}
|
||||
|
||||
public static GetFormResolver(
|
||||
item: ItemCardType | ItemCreateType | ItemType
|
||||
) {
|
||||
return this.itemsConfiguration[item.type].formResolver;
|
||||
}
|
||||
|
||||
public static GetSectionUrlByItemType(
|
||||
item: ItemCardType | ItemCreateType | ItemType
|
||||
) {
|
||||
return this.itemsConfiguration[item.type].sectionUrl;
|
||||
}
|
||||
|
||||
public static GetPropertiesDescriptionForItem<
|
||||
T extends ItemType | ItemCreateType
|
||||
>(item: T) {
|
||||
return this.itemsConfiguration[item.type]
|
||||
.propertiesDescription as ItemPropertiesDescriptionType<T>;
|
||||
}
|
||||
|
||||
public static async AddItem(itemInfo: ItemCreateType) {
|
||||
const item = await this.itemsConfiguration[itemInfo.type].service.Add(
|
||||
itemInfo
|
||||
|
||||
@@ -16,30 +16,12 @@ export type ItemCreateType =
|
||||
| AudiobookCreateType;
|
||||
|
||||
export type UnionItemType = GameType & MovieType & AudiobookType;
|
||||
export type UnionItemCardType = GameCardType &
|
||||
MovieCardType &
|
||||
AudiobookCardType;
|
||||
export type UnionItemCreateType = GameCreateType &
|
||||
MovieCreateType &
|
||||
AudiobookCreateType;
|
||||
|
||||
export enum TypesOfItems {
|
||||
game,
|
||||
movie,
|
||||
audiobook,
|
||||
}
|
||||
|
||||
export type ItemSectionsType = "games" | "movies" | "audiobooks";
|
||||
export const ItemSections = [
|
||||
"games",
|
||||
"movies",
|
||||
"audiobooks",
|
||||
] as ItemSectionsType[];
|
||||
|
||||
export const isSection = (a: string): a is ItemSectionsType => {
|
||||
return (ItemSections as string[]).includes(a);
|
||||
};
|
||||
|
||||
export type ItemPropertiesDescriptionType<T extends ItemType | ItemCreateType> =
|
||||
{
|
||||
name: string;
|
||||
|
||||
2
src/features/sections/index.ts
Normal file
2
src/features/sections/index.ts
Normal file
@@ -0,0 +1,2 @@
|
||||
import { SectionService, type SectionType } from "./sections";
|
||||
export { SectionService, type SectionType };
|
||||
64
src/features/sections/sections.ts
Normal file
64
src/features/sections/sections.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { TypesOfItems } from "@/entities/item";
|
||||
|
||||
export type SectionType = (typeof SectionService.sections)[number];
|
||||
|
||||
export abstract class SectionService {
|
||||
static get itemTypeToSection(): { [k in TypesOfItems]: SectionType } {
|
||||
return {
|
||||
[TypesOfItems.game]: "games",
|
||||
[TypesOfItems.movie]: "movies",
|
||||
[TypesOfItems.audiobook]: "audiobooks",
|
||||
};
|
||||
}
|
||||
|
||||
static get sectionsConfiguration(): {
|
||||
[k in SectionType]: {
|
||||
sectionName: string;
|
||||
sectionUrl: string;
|
||||
itemType: TypesOfItems;
|
||||
popularSubsectionName: string;
|
||||
sectionInviteText: string;
|
||||
addItemText: string;
|
||||
sectionDescription: string;
|
||||
};
|
||||
} {
|
||||
return {
|
||||
games: {
|
||||
sectionName: "Игры",
|
||||
sectionUrl: "games",
|
||||
itemType: TypesOfItems.game,
|
||||
popularSubsectionName: "Популярные игры",
|
||||
sectionInviteText: 'Перейти в раздел "Игры"',
|
||||
addItemText: "Добавить игру",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена актуальными версиями популярных игр",
|
||||
},
|
||||
movies: {
|
||||
sectionName: "Фильмы",
|
||||
sectionUrl: "movies",
|
||||
itemType: TypesOfItems.movie,
|
||||
popularSubsectionName: "Популярные фильмы",
|
||||
sectionInviteText: 'Перейти в раздел "Фильмы"',
|
||||
addItemText: "Добавить фильм",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена популярными фильмами в лучшем качестве",
|
||||
},
|
||||
audiobooks: {
|
||||
sectionName: "Аудиокниги",
|
||||
sectionUrl: "audiobooks",
|
||||
itemType: TypesOfItems.audiobook,
|
||||
popularSubsectionName: "Популярные аудиокниги",
|
||||
sectionInviteText: 'Перейти в раздел "Аудиокниги"',
|
||||
addItemText: "Добавить аудиокнигу",
|
||||
sectionDescription:
|
||||
"каталог .torrent файлов для обмена популярными аудиокнигами любимых авторов",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
static sections = ["games", "movies", "audiobooks"] as const;
|
||||
|
||||
static isSection = (a: string): a is SectionType => {
|
||||
return this.sections.includes(a as SectionType);
|
||||
};
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import useSWR, { mutate } from "swr";
|
||||
import clsx from "clsx";
|
||||
import Cookies from "js-cookie";
|
||||
import { useState } from "react";
|
||||
import { ItemService } from "@/entities/item";
|
||||
import { SectionService } from "../sections";
|
||||
|
||||
export const UserActivities = () => {
|
||||
const { data: me } = useSWR("user", () => UserService.IdentifyYourself());
|
||||
@@ -39,14 +39,13 @@ export const UserActivities = () => {
|
||||
{[
|
||||
{
|
||||
group: "Добавить:",
|
||||
items: Object.entries(ItemService.itemSections).map(
|
||||
([sectionId, section]) => {
|
||||
items: SectionService.sections.map((section) => {
|
||||
return {
|
||||
name: section.addItemText,
|
||||
link: `/${sectionId}/add`,
|
||||
name: SectionService.sectionsConfiguration[section]
|
||||
.addItemText,
|
||||
link: `/${SectionService.sectionsConfiguration[section].sectionUrl}/add`,
|
||||
};
|
||||
}
|
||||
),
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "Выйти",
|
||||
|
||||
@@ -33,7 +33,6 @@ export abstract class HTTPService {
|
||||
schema: Z,
|
||||
options?: RequestOptions
|
||||
) {
|
||||
console.log(options?.body);
|
||||
return await fetch(process.env.NEXT_PUBLIC_BASE_URL + url, {
|
||||
method: method,
|
||||
headers: {
|
||||
|
||||
@@ -7,7 +7,7 @@ import Link from "next/link";
|
||||
import { useSelectedLayoutSegment } from "next/navigation";
|
||||
import clsx from "clsx";
|
||||
import { UserActivities } from "@/features/userActivities";
|
||||
import { ItemSections, ItemService } from "@/entities/item";
|
||||
import { SectionService } from "@/features/sections";
|
||||
|
||||
export const Header = () => {
|
||||
const currentPageName = useSelectedLayoutSegment();
|
||||
@@ -25,7 +25,7 @@ export const Header = () => {
|
||||
<Link href="/">.Torrent</Link>
|
||||
</h1>
|
||||
<div className="hidden text-2xl lp:block">
|
||||
{ItemSections.map((section) => (
|
||||
{SectionService.sections.map((section) => (
|
||||
<Link
|
||||
key={section}
|
||||
className={clsx(
|
||||
@@ -34,7 +34,7 @@ export const Header = () => {
|
||||
)}
|
||||
href={"/" + section}
|
||||
>
|
||||
{ItemService.itemSections[section].sectionName}
|
||||
{SectionService.sectionsConfiguration[section].sectionName}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { ItemSections, ItemService } from "@/entities/item";
|
||||
import { SectionService } from "@/features/sections";
|
||||
import clsx from "clsx";
|
||||
import Link from "next/link";
|
||||
import { useState } from "react";
|
||||
@@ -32,13 +32,13 @@ export const MobileMenu = () => {
|
||||
)}
|
||||
onClick={() => changeMenuOpen(false)}
|
||||
>
|
||||
{ItemSections.map((section) => (
|
||||
{SectionService.sections.map((section) => (
|
||||
<Link
|
||||
key={section}
|
||||
className="text-xl py-2 cursor-pointer hover:underline"
|
||||
href={"/" + section}
|
||||
>
|
||||
{ItemService.itemSections[section].sectionName}
|
||||
{SectionService.sectionsConfiguration[section].sectionName}
|
||||
</Link>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
ItemCardType,
|
||||
ItemService,
|
||||
} from "@/entities/item";
|
||||
import { SectionService } from "@/features/sections";
|
||||
import { Img } from "@/shared/ui";
|
||||
import Link from "next/link";
|
||||
|
||||
@@ -12,7 +13,14 @@ export const ItemCard = ({ card }: { card: ItemCardType }) => {
|
||||
return (
|
||||
<Link
|
||||
className="group/itemcard cursor-pointer"
|
||||
href={"/" + ItemService.GetSectionUrlByItemType(card) + "/" + card.id}
|
||||
href={
|
||||
"/" +
|
||||
SectionService.sectionsConfiguration[
|
||||
SectionService.itemTypeToSection[card.type]
|
||||
].sectionUrl +
|
||||
"/" +
|
||||
card.id
|
||||
}
|
||||
>
|
||||
{!!card.cover && (
|
||||
<Img
|
||||
@@ -44,15 +44,15 @@ export const ItemInfo = <T extends ItemType | ItemCreateType>({
|
||||
register,
|
||||
handleSubmit,
|
||||
setValue,
|
||||
setError,
|
||||
watch,
|
||||
reset,
|
||||
formState: { dirtyFields, errors },
|
||||
} = useForm<ItemType | ItemCreateType>({
|
||||
// Unfortunately, react hook form does not accept generic type correctly
|
||||
// useForm<T> causes an error when calling register(key) ->
|
||||
// key is not assignable to parameter of type 'Path<T>'
|
||||
defaultValues: init_item,
|
||||
resolver: zodResolver(ItemService.GetFormResolver(item)),
|
||||
resolver: zodResolver(
|
||||
ItemService.itemsConfiguration[item.type].formResolver
|
||||
),
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -72,7 +72,6 @@ export const ItemInfo = <T extends ItemType | ItemCreateType>({
|
||||
useEffect(() => {
|
||||
if (!Object.keys(dirtyFields).length) return;
|
||||
if (JSON.stringify(watchedData) === JSON.stringify(formData)) return;
|
||||
console.log(dirtyFields);
|
||||
changeFormData(watchedData as T);
|
||||
if (savedTimeout) clearTimeout(savedTimeout);
|
||||
changeSavedTimeout(
|
||||
@@ -83,14 +82,15 @@ export const ItemInfo = <T extends ItemType | ItemCreateType>({
|
||||
}, [watchedData]);
|
||||
|
||||
const onSubmit = async (formData: ItemCreateType) => {
|
||||
changeSavedTimeout(null);
|
||||
console.log(formData);
|
||||
const updatedItem = ItemService.isExistingItem(item)
|
||||
? await ItemService.ChangeItem(item.id, formData)
|
||||
: await ItemService.AddItem(formData);
|
||||
changeSavedTimeout(null);
|
||||
if (updatedItem) {
|
||||
changeItem(updatedItem as T);
|
||||
reset({}, { keepValues: true });
|
||||
} else {
|
||||
setError("root", { message: "Ошибка сервера" });
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ItemCreateType, ItemType } from "@/entities/item";
|
||||
import { ItemService } from "@/entities/item/item";
|
||||
import { ItemPropertiesDescriptionType } from "@/entities/item/types";
|
||||
import clsx from "clsx";
|
||||
import { UseFormRegister, UseFormSetValue } from "react-hook-form";
|
||||
|
||||
@@ -23,8 +24,10 @@ export const ItemProperties = <T extends ItemType | ItemCreateType>({
|
||||
!editable && "cursor-default"
|
||||
)}
|
||||
>
|
||||
{(ItemService.GetPropertiesDescriptionForItem(item) ?? []).map(
|
||||
(section, i) => (
|
||||
{(
|
||||
ItemService.itemsConfiguration[item.type]
|
||||
.propertiesDescription as ItemPropertiesDescriptionType<T>
|
||||
).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="text-sm lp:text-md py-1">
|
||||
@@ -77,8 +80,7 @@ export const ItemProperties = <T extends ItemType | ItemCreateType>({
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -5,7 +5,6 @@ import Link from "next/link";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { useEffect, useState } from "react";
|
||||
import Masonry, { ResponsiveMasonry } from "react-responsive-masonry";
|
||||
import { boolean } from "zod";
|
||||
|
||||
export const Section = ({
|
||||
name,
|
||||
|
||||
Reference in New Issue
Block a user