This commit is contained in:
2024-03-04 04:15:58 +03:00
parent 0db252bb27
commit 659d76b694
18 changed files with 366 additions and 75 deletions

View File

@@ -2,7 +2,7 @@ import {FC} from "react";
import styles from './Board.module.css';
import {Divider, Text, Title} from '@mantine/core';
import {Draggable, Droppable} from "@hello-pangea/dnd";
import CreateLeadButton from "../CreateLeadButton/CreateLeadButton.tsx";
import CreateDealButton from "../CreateDealButton/CreateDealButton.tsx";
type Props = {
droppableId: string;
@@ -21,16 +21,16 @@ export const Board: FC<Props> = ({droppableId, title, withCreateButton = false})
<Divider size={"xl"} my={10} color={"blue"}/>
</div>
<Droppable droppableId={droppableId}>
{(provided, snapshot) => (
{(provided) => (
<div ref={provided.innerRef} className={styles["items-list"]}>
{withCreateButton &&
<CreateLeadButton
<CreateDealButton
onClick={() => {
}}
/>}
<Draggable draggableId={droppableId + '1'} index={1}>
{(provided, snapshot) => (
{(provided) => (
<div {...provided.draggableProps}
{...provided.dragHandleProps}
ref={provided.innerRef}

View File

@@ -0,0 +1,31 @@
import {FC, useState} from "react";
import styles from './CreateDealButton.module.css';
import {Button, rem, Text, TextInput, Transition} from '@mantine/core';
import CreateDealFrom from "../CreateDealForm/CreateDealFrom.tsx";
type Props = {
onClick: () => void;
}
const CreateDealButton: FC<Props> = ({onClick}) => {
const [isCreating, setIsCreating] = useState(false);
return (
<div className={styles['container']}
onClick={() => {
if (isCreating) return;
setIsCreating(prevState => !prevState)
}}
>
<Text>Быстрое добавление</Text>
<CreateDealFrom
onCancel={() => {
}}
onSubmit={() => {
}}
/>
</div>
)
}
export default CreateDealButton;

View File

@@ -0,0 +1,15 @@
.inputs {
display: flex;
flex-direction: column;
width: 100%
}
.inputs * {
width: 100%;
}
.buttons {
display: flex;
gap: rem(10);
}

View File

@@ -0,0 +1,83 @@
import {Button, rem, Textarea, TextInput} from "@mantine/core";
import {QuickDeal} from "../../../types/QuickDeal.ts";
import {FC} from "react";
import {useForm} from "@mantine/form";
import styles from './CreateDealForm.module.css';
import ClientSelect from "../../Selects/ClientSelect/ClientSelect.tsx";
import {DateTimePicker} from "@mantine/dates";
type Props = {
onSubmit: (quickDeal: QuickDeal) => void
onCancel: () => void;
}
const CreateDealFrom: FC<Props> = ({onSubmit, onCancel}) => {
const form = useForm({
initialValues: {
name: '',
clientName: '',
clientAddress: '',
comment: '',
acceptance_date: new Date()
}
});
return (
<form
style={{width: '100%'}}
onSubmit={form.onSubmit((values) => console.log(values))}
>
<div style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: rem(10),
padding: rem(10)
}}>
<div className={styles['inputs']}>
<TextInput
placeholder={'Название'}
{...form.getInputProps('name')}
/>
</div>
<div className={styles['inputs']}>
<ClientSelect
withAddress
nameRestProps={form.getInputProps('clientName')}
addressRestProps={form.getInputProps('clientAddress')}
onSelect={() => {
}}/>
</div>
<div className={styles['inputs']}>
<Textarea
autosize
placeholder={'Комментарий'}
minRows={2}
maxRows={4}
{...form.getInputProps('comment')}
/>
</div>
<div className={styles['inputs']}>
<DateTimePicker
placeholder={'Дата приемки'}
/>
</div>
<div className={styles['buttons']}>
<Button
type={'submit'}
>Добавить</Button>
<Button
variant={'outline'}
onClick={() => onCancel()}
>Отменить</Button>
</div>
</div>
</form>
)
}
export default CreateDealFrom;

View File

@@ -1,60 +0,0 @@
import React, {FC, useState} from "react";
import styles from './CreateLeadButton.module.css';
import {Button, Center, rem, Text, TextInput, Transition} from '@mantine/core';
type Props = {
onClick: () => void;
}
const CreateLeadButton: FC<Props> = ({onClick}) => {
const [isCreating, setIsCreating] = useState(false);
const [showButton, setShowButton] = useState(true);
console.log(`isCreating: ${isCreating}`)
console.log(`showButton: ${showButton}`)
return (
<div className={styles['container']}
onClick={() => {
if (isCreating) return;
setIsCreating(prevState => !prevState)
setShowButton(false);
}}
>
{(!isCreating && showButton) &&
<Text>Быстрое добавление</Text>
}
<Transition
mounted={isCreating}
transition={'scale-y'}
duration={300}
// onExited={()=>setShowButton(true)}
keepMounted
>
{(styles) => <div style={{...styles, width: '100%'}}>
<div style={{
display: 'flex',
flexDirection: 'column',
width: '100%',
gap: rem(10),
padding: rem(10)
}}>
<div style={{display: "flex", flexDirection: "column", width: '100%'}}>
<TextInput placeholder={'Название'} w={'100%'}/>
</div>
<div style={{display: "flex", flexDirection: "column", width: '100%'}}>
<TextInput placeholder={'Компания: название'} w={'100%'}/>
<TextInput placeholder={'Компания: адрес'} w={'100%'}/>
</div>
<div style={{gap:rem(10), display:"flex"}}>
<Button>Добавить</Button>
<Button variant={'outline'} onClick={()=>setIsCreating(false)}>Отменить</Button>
</div>
</div>
</div>}
</Transition>
</div>
)
}
export default CreateLeadButton;

View File

@@ -0,0 +1,87 @@
import {useDebouncedValue} from "@mantine/hooks";
import {Autocomplete, AutocompleteProps, TextInput, TextInputProps} from "@mantine/core";
import {FC, useEffect, useState} from "react";
import {Client} from "../../../types/Client.ts";
import {ClientService} from "../../../client";
type Props = {
onSelect?: (client: Client) => void;
withAddress?: boolean;
nameRestProps?: AutocompleteProps;
addressRestProps?: TextInputProps;
}
const ClientSelect: FC<Props> = ({onSelect, addressRestProps, nameRestProps, withAddress = false}) => {
const [value, setValue] = useState('');
const [debouncedValue] = useDebouncedValue(value, 200);
// const [isLoading, setIsLoading] = useState(false);
const [clients, setClients] = useState<Client[]>([])
const [selectedClient, selectClient] = useState<Client>();
const handleChange = (value: string) => {
setClients([]);
setValue(value);
}
const handleDebouncedChange = () => {
if (!value.trim()) return;
// setIsLoading(true);
ClientService.searchClients({name: value}).then(({clients}) => {
setClients(clients);
// setIsLoading(false);
})
}
useEffect(() => {
handleDebouncedChange();
}, [debouncedValue]);
useEffect(() => {
selectClient(clients.find(client =>
client.name.toLowerCase().trim() == value.toLowerCase().trim())
||
{
name: value,
id: -1,
address: ''
});
}, [value]);
useEffect(() => {
if (!selectedClient) return;
if (onSelect) onSelect(selectedClient);
if (nameRestProps?.onChange) nameRestProps.onChange(selectedClient.name);
if (addressRestProps?.onChange) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-expect-error
addressRestProps.onChange(selectedClient.address);
}
}, [selectedClient]);
return (
<>
<Autocomplete
{...nameRestProps}
placeholder={'Клиент: название'}
onChange={handleChange}
value={value}
data={clients.map(client => client.name)}
styles={withAddress ? {
input: {
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0
}
} : {}}
/>
{withAddress &&
<TextInput
placeholder={'Клиент: адрес'}
value={selectedClient?.address}
onChange={event => {
selectClient(prevState => prevState && {...prevState, address: event.target.value})
}}
/>
}
</>
)
}
export default ClientSelect;