Skip to content
Snippets Groups Projects
Commit e6173b17 authored by Piotr Gawron's avatar Piotr Gawron
Browse files

modal for adding comments

parent 8ea0a1ad
No related branches found
No related tags found
2 merge requests!223reset the pin numbers before search results are fetch (so the results will be...,!202Resolve "[MIN-264] Right click - Add comment"
import { StoreType } from '@/redux/store';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import {
InitialStoreState,
getReduxWrapperWithStore,
} from '@/utils/testing/getReduxWrapperWithStore';
import { act } from 'react-dom/test-utils';
import { mockNetworkResponse } from '@/utils/mockNetworkResponse';
import { MODAL_INITIAL_STATE_MOCK } from '@/redux/modal/modal.mock';
import { AddCommentModal } from '@/components/FunctionalArea/Modal/AddCommentModal/AddCommentModal.component';
mockNetworkResponse();
const renderComponent = (initialStoreState: InitialStoreState = {}): { store: StoreType } => {
const { Wrapper, store } = getReduxWrapperWithStore(initialStoreState);
return (
render(
<Wrapper>
<AddCommentModal />
</Wrapper>,
),
{
store,
}
);
};
describe('AddCommentModal - component', () => {
test('renders AddCommentModal component', () => {
renderComponent();
const emailInput = screen.getByLabelText(/email/i);
const contentInput = screen.getByLabelText(/content/i);
expect(emailInput).toBeInTheDocument();
expect(contentInput).toBeInTheDocument();
});
test('handles input change correctly', () => {
renderComponent();
const emailInput: HTMLInputElement = screen.getByLabelText(/email/i);
const contentInput: HTMLInputElement = screen.getByLabelText(/content/i);
fireEvent.change(emailInput, { target: { value: 'test@email.pl' } });
fireEvent.change(contentInput, { target: { value: 'test content' } });
expect(emailInput.value).toBe('test@email.pl');
expect(contentInput.value).toBe('test content');
});
test('submits form', async () => {
const { store } = renderComponent({
modal: {
...MODAL_INITIAL_STATE_MOCK,
isOpen: true,
modalName: 'add-comment',
},
});
const emailInput: HTMLInputElement = screen.getByLabelText(/email/i);
const contentInput: HTMLInputElement = screen.getByLabelText(/content/i);
const submitButton = screen.getByText(/submit/i);
fireEvent.change(emailInput, { target: { value: 'test@email.pl' } });
fireEvent.change(contentInput, { target: { value: 'test content' } });
act(() => {
submitButton.click();
});
await waitFor(() => {
const modalState = store.getState().modal;
expect(modalState.isOpen).toBeFalsy();
expect(modalState.modalName).toBe('none');
});
});
});
import { useAppDispatch } from '@/redux/hooks/useAppDispatch';
import { Button } from '@/shared/Button';
import { Input } from '@/shared/Input';
import React from 'react';
import { addComment } from '@/redux/comment/thunks/addComment';
import { useAppSelector } from '@/redux/hooks/useAppSelector';
import { currentModelIdSelector } from '@/redux/models/models.selectors';
import { closeModal } from '@/redux/modal/modal.slice';
export const AddCommentModal: React.FC = () => {
const dispatch = useAppDispatch();
const modelId = useAppSelector(currentModelIdSelector);
const [data, setData] = React.useState({ email: '', content: '', modelId });
const handleChange = (e: React.ChangeEvent<HTMLInputElement>): void => {
const { name, value } = e.target;
setData(prevData => ({ ...prevData, [name]: value }));
};
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>): Promise<void> => {
e.preventDefault();
await dispatch(addComment(data));
dispatch(closeModal());
};
return (
<div className="w-[400px] border border-t-[#E1E0E6] bg-white p-[24px]">
<form onSubmit={handleSubmit}>
<label className="mb-5 block text-sm font-semibold" htmlFor="email">
Email (visible only to moderators):
<Input
type="text"
name="email"
id="email"
placeholder="Your email here..."
value={data.email}
onChange={handleChange}
className="mt-2.5 text-sm font-medium text-font-400"
/>
</label>
<label className="text-sm font-semibold" htmlFor="content">
Content:
<Input
type="textarea"
name="content"
id="content"
placeholder="Message here..."
value={data.content}
onChange={handleChange}
className="mt-2.5 text-sm font-medium text-font-400"
/>
</label>
<Button type="submit" className="w-full justify-center text-base font-medium">
Submit
</Button>
</form>
</div>
);
};
import { ZOD_SEED } from '@/constants';
// eslint-disable-next-line import/no-extraneous-dependencies
import { createFixture } from 'zod-fixture';
import { commentSchema } from '@/models/commentSchema';
export const commentFixture = createFixture(commentSchema, {
seed: ZOD_SEED,
});
......@@ -99,4 +99,5 @@ export const apiPath = {
logout: (): string => `doLogout`,
userPrivileges: (login: string): string => `users/${login}?columns=privileges`,
getComments: (): string => `projects/${PROJECT_ID}/comments/models/*/`,
addComment: (modelId: number): string => `projects/${PROJECT_ID}/comments/models/${modelId}/`,
};
......@@ -15,3 +15,9 @@ export type GetElementProps = {
elementId: number;
modelId: number;
};
export type AddCommentProps = {
email: string;
content: string;
modelId: number;
};
import { commentSchema } from '@/models/commentSchema';
import { apiPath } from '@/redux/apiPath';
import { axiosInstance } from '@/services/api/utils/axiosInstance';
import { ThunkConfig } from '@/types/store';
import { validateDataUsingZodSchema } from '@/utils/validateDataUsingZodSchema';
import { createAsyncThunk } from '@reduxjs/toolkit';
import { Comment } from '@/types/models';
import { AddCommentProps } from '@/redux/comment/comment.types';
export const addComment = createAsyncThunk<Comment | null, AddCommentProps, ThunkConfig>(
'project/getComments',
async ({ email, content, modelId }) => {
try {
const payload = { email, content };
const response = await axiosInstance.post<Comment>(apiPath.addComment(modelId), payload);
const isDataValid = validateDataUsingZodSchema(response.data, commentSchema);
return isDataValid ? response.data : null;
} catch (error) {
return Promise.reject(error);
}
},
);
export type ModalName =
| 'none'
| 'add-comment'
| 'overview-images'
| 'mol-art'
| 'login'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment