diff --git a/src/api/notes/index.ts b/src/api/notes/index.ts index 21206e45..9380ff74 100644 --- a/src/api/notes/index.ts +++ b/src/api/notes/index.ts @@ -1,8 +1,20 @@ -import { ApiGetNotesRequest, ApiGetNotesResponse } from '~/api/notes/types'; -import { URLS } from '~/constants/urls'; -import { api, cleanResult } from '~/utils/api'; +import { + ApiGetNotesRequest, + ApiGetNotesResponse, + ApiPostNoteRequest, + ApiPostNoteResponse, +} from "~/api/notes/types"; +import { URLS } from "~/constants/urls"; +import { api, cleanResult } from "~/utils/api"; export const apiGetNotes = ({ limit, offset, search }: ApiGetNotesRequest) => api .get(URLS.NOTES, { params: { limit, offset, search } }) .then(cleanResult); + +export const apiPostNote = ({ text }: ApiPostNoteRequest) => + api + .post(URLS.NOTES, { + text, + }) + .then(cleanResult); diff --git a/src/api/notes/types.ts b/src/api/notes/types.ts index 921b686e..42c76327 100644 --- a/src/api/notes/types.ts +++ b/src/api/notes/types.ts @@ -1,4 +1,4 @@ -import { Note } from '~/types/notes'; +import { Note } from "~/types/notes"; export interface ApiGetNotesRequest { limit: number; @@ -10,3 +10,9 @@ export interface ApiGetNotesResponse { list: Note[]; totalCount: number; } + +export interface ApiPostNoteRequest { + text: string; +} + +export interface ApiPostNoteResponse extends Note {} diff --git a/src/components/notes/NoteCard/index.tsx b/src/components/notes/NoteCard/index.tsx index a87cf6aa..546834fa 100644 --- a/src/components/notes/NoteCard/index.tsx +++ b/src/components/notes/NoteCard/index.tsx @@ -1,12 +1,12 @@ -import React, { VFC } from 'react'; +import React, { VFC } from "react"; -import { Card } from '~/components/containers/Card'; -import { Markdown } from '~/components/containers/Markdown'; -import { Padder } from '~/components/containers/Padder'; -import { NoteMenu } from '~/components/notes/NoteMenu'; -import { formatText, getPrettyDate } from '~/utils/dom'; +import { Card } from "~/components/containers/Card"; +import { Markdown } from "~/components/containers/Markdown"; +import { Padder } from "~/components/containers/Padder"; +import { NoteMenu } from "~/components/notes/NoteMenu"; +import { formatText, getPrettyDate } from "~/utils/dom"; -import styles from './styles.module.scss'; +import styles from "./styles.module.scss"; interface NoteCardProps { content: string; @@ -17,7 +17,10 @@ const NoteCard: VFC = ({ content, createdAt }) => ( - + {getPrettyDate(createdAt)} diff --git a/src/components/notes/NoteCard/styles.module.scss b/src/components/notes/NoteCard/styles.module.scss index 2a7e7c8c..c909430b 100644 --- a/src/components/notes/NoteCard/styles.module.scss +++ b/src/components/notes/NoteCard/styles.module.scss @@ -6,10 +6,6 @@ word-break: break-word; padding: 0; position: relative; - - & > * { - @include row_shadow; - } } .footer { diff --git a/src/components/notes/NoteCreationForm/index.tsx b/src/components/notes/NoteCreationForm/index.tsx new file mode 100644 index 00000000..9d60b761 --- /dev/null +++ b/src/components/notes/NoteCreationForm/index.tsx @@ -0,0 +1,97 @@ +import React, { FC, useCallback, useState } from "react"; + +import { FormikConfig, useFormik } from "formik"; +import { object, string, Asserts } from "yup"; + +import { Card } from "~/components/containers/Card"; +import { Filler } from "~/components/containers/Filler"; +import { Group } from "~/components/containers/Group"; +import { Button } from "~/components/input/Button"; +import { Textarea } from "~/components/input/Textarea"; +import { useRandomPhrase } from "~/constants/phrases"; +import { Note } from "~/types/notes"; +import { getErrorMessage } from "~/utils/errors/getErrorMessage"; +import { showErrorToast } from "~/utils/errors/showToast"; + +import styles from "./styles.module.scss"; + +interface NoteCreationFormProps { + onSubmit: (text: string, callback: (note: Note) => void) => void; + onCancel: () => void; +} + +const validationSchema = object({ + text: string().required("Напишите что-нибудь"), +}); + +type Values = Asserts; + +const NoteCreationForm: FC = ({ + onSubmit, + onCancel, +}) => { + const placeholder = useRandomPhrase("SIMPLE"); + + const submit = useCallback["onSubmit"]>( + async ({ text }, { resetForm, setSubmitting, setErrors }) => { + try { + await onSubmit(text, () => resetForm()); + } catch (error) { + const message = getErrorMessage(error); + if (message) { + setErrors({ text: message }); + return; + } + + showErrorToast(error); + } finally { + setSubmitting(false); + } + }, + [onSubmit], + ); + + const { + values, + errors, + handleChange, + handleSubmit, + touched, + handleBlur, + } = useFormik({ + initialValues: { text: "" }, + validationSchema, + onSubmit: submit, + }); + + return ( +
+ +
+