1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-25 21:06:42 +07:00

Добавили заметки в сайдбар (#126)

* added notes sidebar

* added note dropping and editing

* added sidebar navigation

* handling sidebarchanges over time

* using router back for closing sidebar

* fixed tripping inside single sidebar

* added superpowers toggle to sidebar

* user button opens sidebar now

* added profile cover for profile sidebar

* removed profile sidebar completely

* ran prettier over project

* added note not found error literal
This commit is contained in:
muerwre 2022-08-12 14:07:19 +07:00 committed by GitHub
parent fe3db608d6
commit 5d34090238
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
72 changed files with 1241 additions and 664 deletions

View file

@ -1,4 +1,4 @@
import React, { VFC } from 'react';
import React, { useCallback, useState, VFC } from 'react';
import { Card } from '~/components/containers/Card';
import { Markdown } from '~/components/containers/Markdown';
@ -6,22 +6,56 @@ import { Padder } from '~/components/containers/Padder';
import { NoteMenu } from '~/components/notes/NoteMenu';
import { formatText, getPrettyDate } from '~/utils/dom';
import { NoteCreationForm } from '../NoteCreationForm';
import styles from './styles.module.scss';
interface NoteCardProps {
content: string;
remove: () => Promise<void>;
update: (text: string, callback?: () => void) => Promise<void>;
createdAt: string;
}
const NoteCard: VFC<NoteCardProps> = ({ content, createdAt }) => (
<Card className={styles.note}>
<Padder>
<NoteMenu onEdit={console.log} onDelete={console.log} />
<Markdown className={styles.wrap} dangerouslySetInnerHTML={{ __html: formatText(content) }} />
</Padder>
const NoteCard: VFC<NoteCardProps> = ({
content,
createdAt,
remove,
update,
}) => {
const [editing, setEditing] = useState(false);
<Padder className={styles.footer}>{getPrettyDate(createdAt)}</Padder>
</Card>
);
const toggleEditing = useCallback(() => setEditing(v => !v), []);
const onUpdate = useCallback(
(text: string, callback?: () => void) =>
update(text, () => {
setEditing(false);
callback?.();
}),
[],
);
return (
<Card className={styles.note}>
{editing ? (
<NoteCreationForm
text={content}
onSubmit={onUpdate}
onCancel={toggleEditing}
/>
) : (
<>
<Padder>
<NoteMenu onEdit={toggleEditing} onDelete={remove} />
<Markdown className={styles.wrap}>{formatText(content)}</Markdown>
</Padder>
<Padder className={styles.footer}>{getPrettyDate(createdAt)}</Padder>
</>
)}
</Card>
);
};
export { NoteCard };

View file

@ -6,10 +6,6 @@
word-break: break-word;
padding: 0;
position: relative;
& > * {
@include row_shadow;
}
}
.footer {

View file

@ -0,0 +1,99 @@
import { FC, useCallback } from 'react';
import { FormikConfig, useFormik } from 'formik';
import { Asserts, object, string } 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 { getErrorMessage } from '~/utils/errors/getErrorMessage';
import { showErrorToast } from '~/utils/errors/showToast';
import styles from './styles.module.scss';
interface NoteCreationFormProps {
text?: string;
onSubmit: (text: string, callback: () => void) => void;
onCancel: () => void;
}
const validationSchema = object({
text: string().required('Напишите что-нибудь'),
});
type Values = Asserts<typeof validationSchema>;
const NoteCreationForm: FC<NoteCreationFormProps> = ({
text = '',
onSubmit,
onCancel,
}) => {
const placeholder = useRandomPhrase('SIMPLE');
const submit = useCallback<FormikConfig<Values>['onSubmit']>(
async (values, { resetForm, setSubmitting, setErrors }) => {
try {
await onSubmit(values.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,
isSubmitting,
} = useFormik<Values>({
initialValues: { text },
validationSchema,
onSubmit: submit,
});
return (
<form onSubmit={handleSubmit}>
<Card className={styles.card}>
<div className={styles.row}>
<Textarea
handler={handleChange('text')}
value={values.text}
error={touched.text ? errors.text : undefined}
onBlur={handleBlur('text')}
placeholder={placeholder}
autoFocus
/>
</div>
<Group horizontal className={styles.row}>
<Filler />
<Button size="mini" type="button" color="link" onClick={onCancel}>
Отмена
</Button>
<Button size="mini" type="submit" color="gray" loading={isSubmitting}>
ОК
</Button>
</Group>
</Card>
</form>
);
};
export { NoteCreationForm };

View file

@ -0,0 +1,11 @@
@import "src/styles/variables";
.card {
padding: 0;
}
.row {
@include row_shadow;
padding: $gap / 2;
}