This commit is contained in:
2025-07-15 13:19:12 +05:00
parent f6271e62de
commit 139e06663f
4 changed files with 68 additions and 39 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ html {
}
*::-webkit-scrollbar {
width: 4px;
width: 12px;
}
*::-webkit-scrollbar-thumb {
+43 -31
View File
@@ -1,47 +1,49 @@
'use client';
"use client";
import { projectsTags } from '@/consts/projectsTags';
import { OpenFormModalWrapper } from '@/hocs/OpenFormModalWrapper';
import { useProjectMutation } from '@/hooks/useProjectMutation';
import { useGetCompaniesQuery } from '@/queries/getCompanies';
import { useModalStore } from '@/stores/useModalStore';
import { Product } from '@/types/Product';
import { Button } from '@/ui/Button';
import { CheckboxesGroup } from '@/ui/CheckboxesGroup';
import { TextInput } from '@/ui/TextInput';
import { projectsTags } from "@/consts/projectsTags";
import { OpenFormModalWrapper } from "@/hocs/OpenFormModalWrapper";
import { useProjectMutation } from "@/hooks/useProjectMutation";
import { useGetCompaniesQuery } from "@/queries/getCompanies";
import { useModalStore } from "@/stores/useModalStore";
import { Product } from "@/types/Product";
import { Button } from "@/ui/Button";
import { CheckboxesGroup } from "@/ui/CheckboxesGroup";
import { TextInput } from "@/ui/TextInput";
import {
FormProvider,
SubmitHandler,
useForm,
useWatch,
} from 'react-hook-form';
import AddIcon from '../../../public/icons/add.svg';
import CloseIcon from '../../../public/icons/close.svg';
import { ImageUploader } from '../ImageUploader';
import { CompanyFormModal } from './CompanyFormModal';
import { FormModalHeader } from './FormModalHeader';
import ReactLenis from 'lenis/react';
import { useLenis } from '@/hooks/useLenis';
} from "react-hook-form";
import AddIcon from "../../../public/icons/add.svg";
import CloseIcon from "../../../public/icons/close.svg";
import { ImageUploader } from "../ImageUploader";
import { CompanyFormModal } from "./CompanyFormModal";
import { FormModalHeader } from "./FormModalHeader";
import ReactLenis from "lenis/react";
import { useLenis } from "@/hooks/useLenis";
export interface IProjectFormInput {
title: string;
englishTitle: string;
companyId?: string;
description: string;
city: string;
englishCity: string;
image: string;
stage: number;
releaseDate: string;
tags: Product[];
}
interface IProjectFormModalProps<TAction extends 'create' | 'edit'> {
interface IProjectFormModalProps<TAction extends "create" | "edit"> {
action: TAction;
defaultValues?: TAction extends 'edit'
defaultValues?: TAction extends "edit"
? IProjectFormInput & { id: string }
: undefined;
}
export function ProjectFormModal<TAction extends 'create' | 'edit'>({
export function ProjectFormModal<TAction extends "create" | "edit">({
action,
defaultValues,
}: IProjectFormModalProps<TAction>) {
@@ -50,28 +52,28 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
const { setModal } = useModalStore();
const { mutate } = useProjectMutation(
action === 'create'
action === "create"
? { action, id: undefined }
: { action, id: defaultValues!.id }
);
const form = useForm<IProjectFormInput>({
defaultValues:
action === 'create'
action === "create"
? {
tags: [],
stage: 1,
releaseDate: new Date().toISOString().split('T')[0],
releaseDate: new Date().toISOString().split("T")[0],
}
: {
...defaultValues,
releaseDate: defaultValues?.releaseDate.split('T')[0],
releaseDate: defaultValues?.releaseDate.split("T")[0],
},
});
const { register, handleSubmit, control } = form;
const description = useWatch({ control, name: 'description' });
const description = useWatch({ control, name: "description" });
// const lenis = useLenis();
@@ -94,7 +96,17 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
label="Название проекта"
placeholder="Название"
/>
<TextInput
name="englishTitle"
label="Название проекта на английском"
placeholder="Название"
/>
<TextInput name="city" label="Город" placeholder="Екатеринбург" />
<TextInput
name="englishCity"
label="Город на английском"
placeholder="Екатеринбург"
/>
<div className="flex flex-col gap-4">
<label htmlFor="tags" className="heading2 font-medium">
Выберите категории
@@ -116,7 +128,7 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
backgroundImage: `url("data:image/svg+xml;charset=UTF-8,<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M12.0001 17.707L19.7072 9.99992L18.293 8.58571L12.0001 14.8786L5.70718 8.58571L4.29297 9.99992L12.0001 17.707Z' fill='white'/></svg>")`,
}}
id="company"
{...register('companyId')}
{...register("companyId")}
className="px-8 py-7 rounded-2xl outline-none bg-[#37393B99] bg-no-repeat bg-[right_32px_top_24px] h-fit font-medium btnl appearance-none"
>
<option value={undefined}>Не выбрано</option>
@@ -131,7 +143,7 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
))}
</select>
<OpenFormModalWrapper
modal={<CompanyFormModal action={'create'} />}
modal={<CompanyFormModal action={"create"} />}
>
<Button
rounded="2xl"
@@ -160,7 +172,7 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
style={{
backgroundImage: `url("data:image/svg+xml;charset=UTF-8,<svg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'><path fill-rule='evenodd' clip-rule='evenodd' d='M12.0001 17.707L19.7072 9.99992L18.293 8.58571L12.0001 14.8786L5.70718 8.58571L4.29297 9.99992L12.0001 17.707Z' fill='white'/></svg>")`,
}}
{...register('stage', { valueAsNumber: true })}
{...register("stage", { valueAsNumber: true })}
id="stage"
className="px-8 py-7 rounded-lg outline-none bg-[#37393B99] bg-no-repeat bg-[right_32px_top_24px] appearance-none btnl"
>
@@ -175,11 +187,11 @@ export function ProjectFormModal<TAction extends 'create' | 'edit'>({
</label>
<input
type="date"
{...register('releaseDate', {
{...register("releaseDate", {
valueAsDate: true,
required: true,
})}
defaultValue={defaultValues?.releaseDate.split('T')[0]}
defaultValue={defaultValues?.releaseDate.split("T")[0]}
id="releaseDate"
className="py-5 border-b border-[#37393B] rounded-lg outline-none bg-transparent text-[#7A7A7A] placeholder:text-[#7A7A7A] btnl"
/>
@@ -57,10 +57,18 @@ export function Clients() {
return (
<div
className="lg:space-y-16 md:max-lg:space-y-12 space-y-10 lg:mt-40 mt-[100px]"
className={`lg:space-y-16 md:max-lg:space-y-12 lg:mt-40 mt-[100px] space-y-10${
shuffled.length % 11 === 0 && isLg
? " mb-[calc(2*(100vw-120px)/11)]"
: shuffled.length % 5 === 0 && isMd
? " mb-[calc(2*(100vw-64px)/5)]"
: shuffled.length % 3 === 0 && isXs
? " mb-[calc(2*(100vw-36px)/3)]"
: ""
}`}
ref={ref}
>
<div className="flex items-center justify-between">
<div className="flex justify-between items-center">
<Title className="mx-auto">
<span className="text-gradient">
{count !== undefined && getCompaniesCount(count)}
@@ -69,7 +77,7 @@ export function Clients() {
</Title>
<OpenFormModalWrapper
modal={<CompanyFormModal action="create" />}
className="aspect-square flex flex-col items-center justify-center gap-3"
className="aspect-square flex flex-col gap-3 justify-center items-center"
>
<GradientButton>
<AddIcon className="w-7 h-7 text-white" />
@@ -109,7 +117,14 @@ export function Clients() {
style={{
left:
(shuffled.length % (isLg ? 11 : isMd ? 5 : 3)) * (size + 6),
bottom: 0,
bottom:
shuffled.length % 11 === 0 && isLg
? "calc((-100vw + 120px) / 11)"
: shuffled.length % 5 === 0 && isMd
? "calc((-100vw + 64px) / 5)"
: shuffled.length % 3 === 0 && isXs
? "calc((-100vw + 36px) / 3)"
: 0,
}}
>
<GradientButton
+5 -3
View File
@@ -1,15 +1,17 @@
import { ICompany } from './ICompany';
import { Product } from './Product';
import { ICompany } from "./ICompany";
import { Product } from "./Product";
export type Device = 'Stream' | 'Touch' | 'Mobile' | 'VR';
export type Device = "Stream" | "Touch" | "Mobile" | "VR";
export interface IProject {
id: string;
title: string;
englishTitle: string;
description: string;
company?: ICompany;
companyId?: string;
city: string;
englishCity: string;
image: string;
stage: number;
releaseDate: string;