diff --git a/.prettierrc.cjs b/.prettierrc.cjs index f0824cd..7cbfb16 100644 --- a/.prettierrc.cjs +++ b/.prettierrc.cjs @@ -1,5 +1,3 @@ module.exports = { ...require('@it-incubator/prettier-config'), - tabWidth: 4, - //override settings here } \ No newline at end of file diff --git a/eslint/index.js b/eslint/index.js index a2bfc1e..120dbb7 100644 --- a/eslint/index.js +++ b/eslint/index.js @@ -2,11 +2,11 @@ const fs = require('fs') const path = require('path') const ruleFiles = fs - .readdirSync(__dirname) - .filter(file => file !== 'index.js' && !file.endsWith('test.js')) + .readdirSync(__dirname) + .filter(file => file !== 'index.js' && !file.endsWith('test.js')) const rules = Object.fromEntries( - ruleFiles.map(file => [path.basename(file, '.js'), require('./' + file)]) + ruleFiles.map(file => [path.basename(file, '.js'), require('./' + file)]) ) module.exports = { rules } diff --git a/eslint/no-wrong-redux-import.js b/eslint/no-wrong-redux-import.js index 1a4c635..f67e735 100644 --- a/eslint/no-wrong-redux-import.js +++ b/eslint/no-wrong-redux-import.js @@ -1,26 +1,26 @@ // @ts-check /** @type {import('eslint').Rule.RuleModule} */ module.exports = { - create(context) { - return { - ImportDeclaration(node) { - if ( - (node.source && node.source.value === '@reduxjs/toolkit/query/') || - node.source.value === '@reduxjs/toolkit/query' - ) { - context.report({ - fix(fixer) { - return fixer.replaceText(node.source, "'@reduxjs/toolkit/query/react'") - }, - message: - "Import from '@reduxjs/toolkit/query/' is disallowed. Please import from '@reduxjs/toolkit/query/react'.", - node, - }) - } + create(context) { + return { + ImportDeclaration(node) { + if ( + (node.source && node.source.value === '@reduxjs/toolkit/query/') || + node.source.value === '@reduxjs/toolkit/query' + ) { + context.report({ + fix(fixer) { + return fixer.replaceText(node.source, "'@reduxjs/toolkit/query/react'") }, + message: + "Import from '@reduxjs/toolkit/query/' is disallowed. Please import from '@reduxjs/toolkit/query/react'.", + node, + }) } - }, - meta: { - fixable: 'code', - }, + }, + } + }, + meta: { + fixable: 'code', + }, } diff --git a/src/App.tsx b/src/App.tsx index 6840898..6f08196 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,9 +4,9 @@ import { Router } from '@/router' import { store } from '@/services/store' export function App() { - return ( - - - - ) + return ( + + + + ) } diff --git a/src/assets/icons/camera.tsx b/src/assets/icons/camera.tsx index 08ff491..6e0d43a 100644 --- a/src/assets/icons/camera.tsx +++ b/src/assets/icons/camera.tsx @@ -1,71 +1,71 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - + x={'0'} + y={'0'} + > + + + + + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/check.tsx b/src/assets/icons/check.tsx index 9e4ab19..10ca424 100644 --- a/src/assets/icons/check.tsx +++ b/src/assets/icons/check.tsx @@ -1,21 +1,21 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/chevron-up.tsx b/src/assets/icons/chevron-up.tsx index e841c88..62b2e88 100644 --- a/src/assets/icons/chevron-up.tsx +++ b/src/assets/icons/chevron-up.tsx @@ -1,28 +1,28 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const ChevronUp = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - + + + + + + + + + + ) const ForwardRef = forwardRef(ChevronUp) const Memo = memo(ForwardRef) diff --git a/src/assets/icons/close.tsx b/src/assets/icons/close.tsx index ec16872..1519dd6 100644 --- a/src/assets/icons/close.tsx +++ b/src/assets/icons/close.tsx @@ -1,37 +1,37 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( + - - - - - - - - - - + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/edit-2-outline.tsx b/src/assets/icons/edit-2-outline.tsx index 5a38c55..8b8ca64 100644 --- a/src/assets/icons/edit-2-outline.tsx +++ b/src/assets/icons/edit-2-outline.tsx @@ -1,33 +1,33 @@ import { SVGProps } from 'react' const SvgComponent = (props: SVGProps) => ( - - - - - - - - - - - + + + + + + + + + + + ) export default SvgComponent diff --git a/src/assets/icons/edit.tsx b/src/assets/icons/edit.tsx index d0ca114..74e78af 100644 --- a/src/assets/icons/edit.tsx +++ b/src/assets/icons/edit.tsx @@ -1,34 +1,34 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - - + + + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) const Memo = memo(ForwardRef) diff --git a/src/assets/icons/email.tsx b/src/assets/icons/email.tsx index a7dda26..7acb4ac 100644 --- a/src/assets/icons/email.tsx +++ b/src/assets/icons/email.tsx @@ -1,100 +1,100 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/eye.tsx b/src/assets/icons/eye.tsx index e029337..af0c18a 100644 --- a/src/assets/icons/eye.tsx +++ b/src/assets/icons/eye.tsx @@ -1,23 +1,23 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/keyboard-arrow-left.tsx b/src/assets/icons/keyboard-arrow-left.tsx index 424847d..7a56039 100644 --- a/src/assets/icons/keyboard-arrow-left.tsx +++ b/src/assets/icons/keyboard-arrow-left.tsx @@ -1,28 +1,26 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - + + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/keyboard-arrow-right.tsx b/src/assets/icons/keyboard-arrow-right.tsx index 2ec3a5e..4d1da91 100644 --- a/src/assets/icons/keyboard-arrow-right.tsx +++ b/src/assets/icons/keyboard-arrow-right.tsx @@ -1,28 +1,26 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - + + + + + + + + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/assets/icons/logo.tsx b/src/assets/icons/logo.tsx index 3ecb322..07fbb01 100644 --- a/src/assets/icons/logo.tsx +++ b/src/assets/icons/logo.tsx @@ -1,34 +1,34 @@ import { SVGProps } from 'react' const SvgComponent = (props: SVGProps) => ( - - - - - + + + + + ) export default SvgComponent diff --git a/src/assets/icons/logout.tsx b/src/assets/icons/logout.tsx index 8d10e81..f66b3ce 100644 --- a/src/assets/icons/logout.tsx +++ b/src/assets/icons/logout.tsx @@ -1,21 +1,23 @@ -import { SVGProps, Ref, forwardRef, memo } from "react" -const SvgComponent = ( - props: SVGProps, - ref: Ref -) => ( - - - - - +import { Ref, SVGProps, forwardRef, memo } from 'react' +const SvgComponent = (props: SVGProps, ref: Ref) => ( + + + + + ) const ForwardRef = forwardRef(SvgComponent) const Memo = memo(ForwardRef) + export default Memo diff --git a/src/assets/icons/person-outline.tsx b/src/assets/icons/person-outline.tsx index f041d38..1c67727 100644 --- a/src/assets/icons/person-outline.tsx +++ b/src/assets/icons/person-outline.tsx @@ -1,26 +1,26 @@ import { SVGProps } from 'react' const SvgComponent = (props: SVGProps) => ( - - - - - - - - - - + + + + + + + + + + ) export default SvgComponent diff --git a/src/assets/icons/play-circle-outline.tsx b/src/assets/icons/play-circle-outline.tsx index 34634e2..d626954 100644 --- a/src/assets/icons/play-circle-outline.tsx +++ b/src/assets/icons/play-circle-outline.tsx @@ -1,33 +1,33 @@ import { SVGProps } from 'react' const SvgComponent = (props: SVGProps) => ( - - - - - - - - - - - + + + + + + + + + + + ) export default SvgComponent diff --git a/src/assets/icons/search.tsx b/src/assets/icons/search.tsx index 55c329d..ec77f00 100644 --- a/src/assets/icons/search.tsx +++ b/src/assets/icons/search.tsx @@ -1,28 +1,28 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - - - - - - - - + + + + + + + + + + ) export default memo(forwardRef(SvgComponent)) diff --git a/src/assets/icons/trash-outline.tsx b/src/assets/icons/trash-outline.tsx index 2a5d157..e711c21 100644 --- a/src/assets/icons/trash-outline.tsx +++ b/src/assets/icons/trash-outline.tsx @@ -1,27 +1,27 @@ import { SVGProps } from 'react' const SvgComponent = (props: SVGProps) => ( - - - - - - - - - - + + + + + + + + + + ) export default SvgComponent diff --git a/src/assets/icons/visibility-off.tsx b/src/assets/icons/visibility-off.tsx index 9cdf760..b4c53e2 100644 --- a/src/assets/icons/visibility-off.tsx +++ b/src/assets/icons/visibility-off.tsx @@ -1,21 +1,21 @@ import { Ref, SVGProps, forwardRef, memo } from 'react' const SvgComponent = (props: SVGProps, ref: Ref) => ( - - - + + + ) const ForwardRef = forwardRef(SvgComponent) diff --git a/src/components/auth/check-email/check-email.stories.tsx b/src/components/auth/check-email/check-email.stories.tsx index a75d80a..7a31ca5 100644 --- a/src/components/auth/check-email/check-email.stories.tsx +++ b/src/components/auth/check-email/check-email.stories.tsx @@ -3,16 +3,16 @@ import type { Meta, StoryObj } from '@storybook/react' import { CheckEmail } from './' const meta = { - component: CheckEmail, - tags: ['autodocs'], - title: 'Auth/Check email', + component: CheckEmail, + tags: ['autodocs'], + title: 'Auth/Check email', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - email: 'your_email@domain.com', - }, + args: { + email: 'your_email@domain.com', + }, } diff --git a/src/components/auth/check-email/check-email.tsx b/src/components/auth/check-email/check-email.tsx index da13510..c34a0b9 100644 --- a/src/components/auth/check-email/check-email.tsx +++ b/src/components/auth/check-email/check-email.tsx @@ -6,26 +6,26 @@ import { Button, Card, Typography } from '../../ui' import s from './check-email.module.scss' type Props = { - email: string + email: string } export const CheckEmail = ({ email }: Props) => { - const message = `We've sent an e-mail with instructions to ${email}` + const message = `We've sent an e-mail with instructions to ${email}` - return ( - - - Check your email - - - - - - {message} - - - Back to Sign in - - - ) + return ( + + + Check your email + + + + + + {message} + + + Back to Sign in + + + ) } diff --git a/src/components/auth/new-password/new-password.stories.tsx b/src/components/auth/new-password/new-password.stories.tsx index 7439d2b..4643097 100644 --- a/src/components/auth/new-password/new-password.stories.tsx +++ b/src/components/auth/new-password/new-password.stories.tsx @@ -3,16 +3,16 @@ import type { Meta, StoryObj } from '@storybook/react' import { NewPassword } from './' const meta = { - component: NewPassword, - tags: ['autodocs'], - title: 'Auth/New password', + component: NewPassword, + tags: ['autodocs'], + title: 'Auth/New password', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - onSubmit: data => console.info(data), - }, + args: { + onSubmit: data => console.info(data), + }, } diff --git a/src/components/auth/new-password/new-password.tsx b/src/components/auth/new-password/new-password.tsx index 38a0d05..a73d999 100644 --- a/src/components/auth/new-password/new-password.tsx +++ b/src/components/auth/new-password/new-password.tsx @@ -8,48 +8,48 @@ import { z } from 'zod' import s from './new-password.module.scss' const schema = z.object({ - password: z.string().nonempty('Enter password'), + password: z.string().nonempty('Enter password'), }) type FormType = z.infer type Props = { - onSubmit: (data: FormType) => void + onSubmit: (data: FormType) => void } export const NewPassword = (props: Props) => { - const { control, handleSubmit } = useForm({ - defaultValues: { - password: '', - }, - resolver: zodResolver(schema), - }) + const { control, handleSubmit } = useForm({ + defaultValues: { + password: '', + }, + resolver: zodResolver(schema), + }) - const handleFormSubmitted = handleSubmit(props.onSubmit) + const handleFormSubmitted = handleSubmit(props.onSubmit) - return ( - <> - - - - Create new password - - - - - Create new password and we will send you further instructions to email - - - Create new password - - - - > - ) + return ( + <> + + + + Create new password + + + + + Create new password and we will send you further instructions to email + + + Create new password + + + + > + ) } diff --git a/src/components/auth/recover-password/recover-password.stories.tsx b/src/components/auth/recover-password/recover-password.stories.tsx index 0e26898..23dec58 100644 --- a/src/components/auth/recover-password/recover-password.stories.tsx +++ b/src/components/auth/recover-password/recover-password.stories.tsx @@ -3,16 +3,16 @@ import type { Meta, StoryObj } from '@storybook/react' import { RecoverPassword } from './' const meta = { - component: RecoverPassword, - tags: ['autodocs'], - title: 'Auth/Recover password', + component: RecoverPassword, + tags: ['autodocs'], + title: 'Auth/Recover password', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - onSubmit: data => console.info(data), - }, + args: { + onSubmit: data => console.info(data), + }, } diff --git a/src/components/auth/recover-password/recover-password.tsx b/src/components/auth/recover-password/recover-password.tsx index e73591c..3914118 100644 --- a/src/components/auth/recover-password/recover-password.tsx +++ b/src/components/auth/recover-password/recover-password.tsx @@ -9,55 +9,51 @@ import { z } from 'zod' import s from './recover-password.module.scss' const schema = z.object({ - email: z.string().email('Invalid email address').nonempty('Enter email'), + email: z.string().email('Invalid email address').nonempty('Enter email'), }) type FormType = z.infer type Props = { - onSubmit: (data: FormType) => void + onSubmit: (data: FormType) => void } export const RecoverPassword = (props: Props) => { - const { control, handleSubmit } = useForm({ - defaultValues: { - email: '', - }, - mode: 'onSubmit', - resolver: zodResolver(schema), - }) + const { control, handleSubmit } = useForm({ + defaultValues: { + email: '', + }, + mode: 'onSubmit', + resolver: zodResolver(schema), + }) - const handleFormSubmitted = handleSubmit(props.onSubmit) + const handleFormSubmitted = handleSubmit(props.onSubmit) - return ( - <> - - - - Forgot your password? - - - - - - - Enter your email address and we will send you further instructions - - - Send Instructions - - - - Did you remember your password? - - - Try logging in - - - > - ) + return ( + <> + + + + Forgot your password? + + + + + + + Enter your email address and we will send you further instructions + + + Send Instructions + + + + Did you remember your password? + + + Try logging in + + + > + ) } diff --git a/src/components/auth/sign-in/sign-in.stories.tsx b/src/components/auth/sign-in/sign-in.stories.tsx index 01bef34..f059f58 100644 --- a/src/components/auth/sign-in/sign-in.stories.tsx +++ b/src/components/auth/sign-in/sign-in.stories.tsx @@ -3,16 +3,16 @@ import type { Meta, StoryObj } from '@storybook/react' import { SignIn } from './' const meta = { - component: SignIn, - tags: ['autodocs'], - title: 'Auth/Sign in', + component: SignIn, + tags: ['autodocs'], + title: 'Auth/Sign in', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - onSubmit: data => console.info(data), - }, + args: { + onSubmit: data => console.info(data), + }, } diff --git a/src/components/auth/sign-in/sign-in.tsx b/src/components/auth/sign-in/sign-in.tsx index 70fa2a8..2a47d2b 100644 --- a/src/components/auth/sign-in/sign-in.tsx +++ b/src/components/auth/sign-in/sign-in.tsx @@ -9,79 +9,79 @@ import { z } from 'zod' import s from './sign-in.module.scss' const schema = z.object({ - email: z.string().email('Invalid email address').nonempty('Enter email'), - password: z.string().nonempty('Enter password'), - rememberMe: z.boolean().optional(), + email: z.string().email('Invalid email address').nonempty('Enter email'), + password: z.string().nonempty('Enter password'), + rememberMe: z.boolean().optional(), }) type FormType = z.infer type Props = { - onSubmit: (data: FormType) => void + onSubmit: (data: FormType) => void } export const SignIn = (props: Props) => { - const { control, handleSubmit } = useForm({ - defaultValues: { - email: '', - password: '', - rememberMe: false, - }, - mode: 'onSubmit', - resolver: zodResolver(schema), - }) + const { control, handleSubmit } = useForm({ + defaultValues: { + email: '', + password: '', + rememberMe: false, + }, + mode: 'onSubmit', + resolver: zodResolver(schema), + }) - const handleFormSubmitted = handleSubmit(props.onSubmit) + const handleFormSubmitted = handleSubmit(props.onSubmit) - return ( - <> - - - - Sign In - - - - - - - - - Forgot Password? - - - Sign In - - - - {`Don't have an account?`} - - - Sign Up - - - > - ) + return ( + <> + + + + Sign In + + + + + + + + + Forgot Password? + + + Sign In + + + + {`Don't have an account?`} + + + Sign Up + + + > + ) } diff --git a/src/components/auth/sign-up/sign-up.stories.tsx b/src/components/auth/sign-up/sign-up.stories.tsx index 2b40cca..2c4ed62 100644 --- a/src/components/auth/sign-up/sign-up.stories.tsx +++ b/src/components/auth/sign-up/sign-up.stories.tsx @@ -3,16 +3,16 @@ import type { Meta, StoryObj } from '@storybook/react' import { SignUp } from './' const meta = { - component: SignUp, - tags: ['autodocs'], - title: 'Auth/Sign up', + component: SignUp, + tags: ['autodocs'], + title: 'Auth/Sign up', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - onSubmit: data => console.info(data), - }, + args: { + onSubmit: data => console.info(data), + }, } diff --git a/src/components/auth/sign-up/sign-up.tsx b/src/components/auth/sign-up/sign-up.tsx index f71d95c..57e3faa 100644 --- a/src/components/auth/sign-up/sign-up.tsx +++ b/src/components/auth/sign-up/sign-up.tsx @@ -10,86 +10,86 @@ import { z } from 'zod' import s from './sign-up.module.scss' const schema = z - .object({ - email: z.string().email('Invalid email address').nonempty('Enter email'), - password: z.string().nonempty('Enter password'), - passwordConfirmation: z.string().nonempty('Confirm your password'), - }) - .superRefine((data, ctx) => { - if (data.password !== data.passwordConfirmation) { - ctx.addIssue({ - code: z.ZodIssueCode.custom, - message: 'Passwords do not match', - path: ['passwordConfirmation'], - }) - } + .object({ + email: z.string().email('Invalid email address').nonempty('Enter email'), + password: z.string().nonempty('Enter password'), + passwordConfirmation: z.string().nonempty('Confirm your password'), + }) + .superRefine((data, ctx) => { + if (data.password !== data.passwordConfirmation) { + ctx.addIssue({ + code: z.ZodIssueCode.custom, + message: 'Passwords do not match', + path: ['passwordConfirmation'], + }) + } - return data - }) + return data + }) type FormType = z.infer type Props = { - onSubmit: (data: Omit) => void + onSubmit: (data: Omit) => void } export const SignUp = (props: Props) => { - const { control, handleSubmit } = useForm({ - defaultValues: { - email: '', - password: '', - passwordConfirmation: '', - }, - mode: 'onSubmit', - resolver: zodResolver(schema), - }) + const { control, handleSubmit } = useForm({ + defaultValues: { + email: '', + password: '', + passwordConfirmation: '', + }, + mode: 'onSubmit', + resolver: zodResolver(schema), + }) - const handleFormSubmitted = handleSubmit(data => - props.onSubmit(omit(data, ['passwordConfirmation'])) - ) + const handleFormSubmitted = handleSubmit(data => + props.onSubmit(omit(data, ['passwordConfirmation'])) + ) - return ( - <> - - - - Sign Up - - - - - - - - - Sign Up - - - {/* eslint-disable-next-line react/no-unescaped-entities */} - - Already have an account? - - - Sign In - - - > - ) + return ( + <> + + + + Sign Up + + + + + + + + + Sign Up + + + {/* eslint-disable-next-line react/no-unescaped-entities */} + + Already have an account? + + + Sign In + + + > + ) } diff --git a/src/components/decks/cards-table.tsx b/src/components/decks/cards-table.tsx index 032e3c5..8ce7ecf 100644 --- a/src/components/decks/cards-table.tsx +++ b/src/components/decks/cards-table.tsx @@ -3,45 +3,45 @@ import { Card } from '@/services/decks' import { formatDate } from '@/utils' const columns: Column[] = [ - { - key: 'question', - sortable: true, - title: 'Question', - }, - { - key: 'answer', - sortable: true, - title: 'Answer', - }, - { - key: 'updated', - sortable: true, - title: 'Last Updated', - }, - { - key: 'grade', - sortable: true, - title: 'Grade', - }, + { + key: 'question', + sortable: true, + title: 'Question', + }, + { + key: 'answer', + sortable: true, + title: 'Answer', + }, + { + key: 'updated', + sortable: true, + title: 'Last Updated', + }, + { + key: 'grade', + sortable: true, + title: 'Grade', + }, ] type Props = { - cards: Card[] | undefined + cards: Card[] | undefined } export const CardsTable = ({ cards }: Props) => { - return ( - - - - {cards?.map(card => ( - - {card.question} - {card.answer} - {formatDate(card.updated)} - {card.grade} - - ))} - - - ) + return ( + + + + {cards?.map(card => ( + + {card.question} + {card.answer} + {formatDate(card.updated)} + {card.grade} + + ))} + + + ) } diff --git a/src/components/decks/deck-dialog/deck-dialog.stories.tsx b/src/components/decks/deck-dialog/deck-dialog.stories.tsx index 5e07e01..d4d602f 100644 --- a/src/components/decks/deck-dialog/deck-dialog.stories.tsx +++ b/src/components/decks/deck-dialog/deck-dialog.stories.tsx @@ -5,68 +5,68 @@ import { Button } from '@/components' import { Meta, StoryObj } from '@storybook/react' const meta = { - component: DeckDialog, - tags: ['autodocs'], - title: 'Decks/Deck Dialog', + component: DeckDialog, + tags: ['autodocs'], + title: 'Decks/Deck Dialog', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - onOpenChange: () => {}, - open: true, - }, - render: args => { - const [open, setOpen] = useState(false) - const closeModal = () => setOpen(false) + args: { + onOpenChange: () => {}, + open: true, + }, + render: args => { + const [open, setOpen] = useState(false) + const closeModal = () => setOpen(false) - return ( - <> - setOpen(true)}>Open Modal - { - console.log(data) - closeModal() - }} - onOpenChange={setOpen} - open={open} - /> - > - ) - }, + return ( + <> + setOpen(true)}>Open Modal + { + console.log(data) + closeModal() + }} + onOpenChange={setOpen} + open={open} + /> + > + ) + }, } export const WithDefaultValues: Story = { - args: { - onOpenChange: () => {}, - open: true, - }, - render: args => { - const [open, setOpen] = useState(false) - const closeModal = () => setOpen(false) + args: { + onOpenChange: () => {}, + open: true, + }, + render: args => { + const [open, setOpen] = useState(false) + const closeModal = () => setOpen(false) - return ( - <> - setOpen(true)}>Open Modal - { - console.log(data) - closeModal() - }} - onOpenChange={setOpen} - open={open} - /> - > - ) - }, + return ( + <> + setOpen(true)}>Open Modal + { + console.log(data) + closeModal() + }} + onOpenChange={setOpen} + open={open} + /> + > + ) + }, } diff --git a/src/components/decks/deck-dialog/deck-dialog.tsx b/src/components/decks/deck-dialog/deck-dialog.tsx index cbcda05..b96999f 100644 --- a/src/components/decks/deck-dialog/deck-dialog.tsx +++ b/src/components/decks/deck-dialog/deck-dialog.tsx @@ -7,52 +7,47 @@ import { z } from 'zod' import s from './deck-dialog.module.scss' const newDeckSchema = z.object({ - isPrivate: z.boolean(), - name: z.string().min(3).max(50), + isPrivate: z.boolean(), + name: z.string().min(3).max(50), }) type FormValues = z.infer type Props = Pick & { - defaultValues?: FormValues - onConfirm: (data: FormValues) => void + defaultValues?: FormValues + onConfirm: (data: FormValues) => void } export const DeckDialog = ({ - defaultValues = { isPrivate: false, name: '' }, - onCancel, - onConfirm, - ...dialogProps + defaultValues = { isPrivate: false, name: '' }, + onCancel, + onConfirm, + ...dialogProps }: Props) => { - const { control, handleSubmit, reset } = useForm({ - defaultValues, - resolver: zodResolver(newDeckSchema), - }) - const onSubmit = handleSubmit(data => { - onConfirm(data) - dialogProps.onOpenChange?.(false) - reset() - }) - const handleCancel = () => { - reset() - onCancel?.() - } + const { control, handleSubmit, reset } = useForm({ + defaultValues, + resolver: zodResolver(newDeckSchema), + }) + const onSubmit = handleSubmit(data => { + onConfirm(data) + dialogProps.onOpenChange?.(false) + reset() + }) + const handleCancel = () => { + reset() + onCancel?.() + } - return ( - - - - - - - ) + return ( + + + + + + + ) } diff --git a/src/components/decks/decks-table.tsx b/src/components/decks/decks-table.tsx index 8441b94..1c6cba5 100644 --- a/src/components/decks/decks-table.tsx +++ b/src/components/decks/decks-table.tsx @@ -2,89 +2,86 @@ import { Link } from 'react-router-dom' import { Edit2Outline, PlayCircleOutline, TrashOutline } from '@/assets' import { - Button, - Column, - Table, - TableBody, - TableCell, - TableHeader, - TableRow, - Typography, + Button, + Column, + Table, + TableBody, + TableCell, + TableHeader, + TableRow, + Typography, } from '@/components' import { Deck } from '@/services/decks' import { formatDate } from '@/utils' import s from './decks-table.module.scss' const columns: Column[] = [ - { - key: 'name', - title: 'Name', - }, - { - key: 'cardsCount', - title: 'Cards', - }, - { - key: 'updated', - title: 'Last Updated', - }, - { - key: 'author', - title: 'Created By', - }, - { - key: 'actions', - title: '', - }, + { + key: 'name', + title: 'Name', + }, + { + key: 'cardsCount', + title: 'Cards', + }, + { + key: 'updated', + title: 'Last Updated', + }, + { + key: 'author', + title: 'Created By', + }, + { + key: 'actions', + title: '', + }, ] type Props = { - currentUserId: string - decks: Deck[] | undefined - onDeleteClick: (id: string) => void - onEditClick: (id: string) => void + currentUserId: string + decks: Deck[] | undefined + onDeleteClick: (id: string) => void + onEditClick: (id: string) => void } export const DecksTable = ({ currentUserId, decks, onDeleteClick, onEditClick }: Props) => { - const handleEditClick = (id: string) => () => onEditClick(id) - const handleDeleteClick = (id: string) => () => onDeleteClick(id) + const handleEditClick = (id: string) => () => onEditClick(id) + const handleDeleteClick = (id: string) => () => onDeleteClick(id) - return ( - - - - {decks?.map(deck => ( - - - - {deck.name} - - - {deck.cardsCount} - {formatDate(deck.updated)} - {deck.author.name} - - - - - - {deck.author.id === currentUserId && ( - <> - - - - - - - > - )} - - - - ))} - - - ) + return ( + + + + {decks?.map(deck => ( + + + + {deck.name} + + + {deck.cardsCount} + {formatDate(deck.updated)} + {deck.author.name} + + + + + + {deck.author.id === currentUserId && ( + <> + + + + + + + > + )} + + + + ))} + + + ) } diff --git a/src/components/decks/delete-deck-dialog/delete-deck-dialog.stories.tsx b/src/components/decks/delete-deck-dialog/delete-deck-dialog.stories.tsx index 27d4b7a..22761e3 100644 --- a/src/components/decks/delete-deck-dialog/delete-deck-dialog.stories.tsx +++ b/src/components/decks/delete-deck-dialog/delete-deck-dialog.stories.tsx @@ -5,35 +5,35 @@ import { Button } from '@/components' import { Meta, StoryObj } from '@storybook/react' const meta = { - component: DeleteDeckDialog, - tags: ['autodocs'], - title: 'Decks/Delete Deck Dialog', + component: DeleteDeckDialog, + tags: ['autodocs'], + title: 'Decks/Delete Deck Dialog', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - deckName: 'Deck Name', - onOpenChange: () => {}, - open: true, - }, - render: args => { - const [open, setOpen] = useState(false) - const closeModal = () => setOpen(false) + args: { + deckName: 'Deck Name', + onOpenChange: () => {}, + open: true, + }, + render: args => { + const [open, setOpen] = useState(false) + const closeModal = () => setOpen(false) - return ( - <> - setOpen(true)}>Open Modal - - > - ) - }, + return ( + <> + setOpen(true)}>Open Modal + + > + ) + }, } diff --git a/src/components/decks/delete-deck-dialog/delete-deck-dialog.tsx b/src/components/decks/delete-deck-dialog/delete-deck-dialog.tsx index e040cfc..0efd454 100644 --- a/src/components/decks/delete-deck-dialog/delete-deck-dialog.tsx +++ b/src/components/decks/delete-deck-dialog/delete-deck-dialog.tsx @@ -3,17 +3,17 @@ import { Dialog, DialogProps } from '@/components' import s from './delete-deck-dialog.module.scss' export default {} type Props = Pick & { - deckName: string + deckName: string } export const DeleteDeckDialog = ({ deckName, ...dialogProps }: Props) => { - return ( - - - - Do you really want to remove {deckName}? - - All cards will be deleted. - - - ) + return ( + + + + Do you really want to remove {deckName}? + + All cards will be deleted. + + + ) } diff --git a/src/components/profile/personal-information/personal-information.stories.tsx b/src/components/profile/personal-information/personal-information.stories.tsx index bf8a4b0..84da9b8 100644 --- a/src/components/profile/personal-information/personal-information.stories.tsx +++ b/src/components/profile/personal-information/personal-information.stories.tsx @@ -3,27 +3,27 @@ import type { Meta, StoryObj } from '@storybook/react' import { PersonalInformation } from './' const meta = { - component: PersonalInformation, - tags: ['autodocs'], - title: 'Profile/Personal information', + component: PersonalInformation, + tags: ['autodocs'], + title: 'Profile/Personal information', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - avatar: 'https://picsum.photos/200', - email: 'your_email@domain.com', - name: 'John Doe', - onAvatarChange: () => { - console.info('avatar changed') - }, - onLogout: () => { - console.info('logout') - }, - onNameChange: () => { - console.info('name changed') - }, + args: { + avatar: 'https://picsum.photos/200', + email: 'your_email@domain.com', + name: 'John Doe', + onAvatarChange: () => { + console.info('avatar changed') }, + onLogout: () => { + console.info('logout') + }, + onNameChange: () => { + console.info('name changed') + }, + }, } diff --git a/src/components/profile/personal-information/personal-information.tsx b/src/components/profile/personal-information/personal-information.tsx index 66cfcbd..042b931 100644 --- a/src/components/profile/personal-information/personal-information.tsx +++ b/src/components/profile/personal-information/personal-information.tsx @@ -4,62 +4,62 @@ import { Button, Card, Typography } from '../../ui' import s from './personal-information.module.scss' type Props = { - avatar: string - email: string - name: string - onAvatarChange: (newAvatar: string) => void - onLogout: () => void - onNameChange: (newName: string) => void + avatar: string + email: string + name: string + onAvatarChange: (newAvatar: string) => void + onLogout: () => void + onNameChange: (newName: string) => void } export const PersonalInformation = ({ - avatar, - email, - name, - onAvatarChange, - onLogout, - onNameChange, + avatar, + email, + name, + onAvatarChange, + onLogout, + onNameChange, }: Props) => { - const handleAvatarChanged = () => { - onAvatarChange('new Avatar') - } - const handleNameChanged = () => { - onNameChange('New name') - } - const handleLogout = () => { - onLogout() - } + const handleAvatarChanged = () => { + onAvatarChange('new Avatar') + } + const handleNameChanged = () => { + onNameChange('New name') + } + const handleLogout = () => { + onLogout() + } - return ( - - - Personal Information - - - - - - - - - - - - {name} - - - - - - - {/* eslint-disable-next-line react/no-unescaped-entities */} - {email} - - - - - Sign Out - - - - ) + return ( + + + Personal Information + + + + + + + + + + + + {name} + + + + + + + {/* eslint-disable-next-line react/no-unescaped-entities */} + {email} + + + + + Sign Out + + + + ) } diff --git a/src/components/ui/button/button.stories.tsx b/src/components/ui/button/button.stories.tsx index c49e6f0..4532de1 100644 --- a/src/components/ui/button/button.stories.tsx +++ b/src/components/ui/button/button.stories.tsx @@ -1,67 +1,71 @@ import type { Meta, StoryObj } from '@storybook/react' import { Button } from './' -import {Camera} from "@/assets"; +import { Camera } from '@/assets' const meta = { - argTypes: { - variant: { - control: { type: 'radio' }, - options: ['primary', 'secondary', 'tertiary', 'link'], - }, + argTypes: { + variant: { + control: { type: 'radio' }, + options: ['primary', 'secondary', 'tertiary', 'link'], }, - component: Button, - tags: ['autodocs'], - title: 'Components/Button', + }, + component: Button, + tags: ['autodocs'], + title: 'Components/Button', } satisfies Meta export default meta type Story = StoryObj export const Primary: Story = { - args: { - children: <>Turn Camera On >, - disabled: false, - variant: 'primary', - }, + args: { + children: ( + <> + Turn Camera On + > + ), + disabled: false, + variant: 'primary', + }, } export const Secondary: Story = { - args: { - children: 'Secondary Button', - disabled: false, - variant: 'secondary', - }, + args: { + children: 'Secondary Button', + disabled: false, + variant: 'secondary', + }, } export const Tertiary: Story = { - args: { - children: 'Tertiary Button', - disabled: false, - variant: 'tertiary', - }, + args: { + children: 'Tertiary Button', + disabled: false, + variant: 'tertiary', + }, } export const Link: Story = { - args: { - children: 'Tertiary Button', - disabled: false, - variant: 'link', - }, + args: { + children: 'Tertiary Button', + disabled: false, + variant: 'link', + }, } export const FullWidth: Story = { - args: { - children: 'Full Width Button', - disabled: false, - fullWidth: true, - variant: 'primary', - }, + args: { + children: 'Full Width Button', + disabled: false, + fullWidth: true, + variant: 'primary', + }, } export const AsLink: Story = { - args: { - as: 'button', - children: 'Link that looks like a button', - variant: 'primary', - href: 'https://google.com', - }, + args: { + as: 'button', + children: 'Link that looks like a button', + href: 'https://google.com', + variant: 'primary', + }, } diff --git a/src/components/ui/button/button.tsx b/src/components/ui/button/button.tsx index 513831c..b835691 100644 --- a/src/components/ui/button/button.tsx +++ b/src/components/ui/button/button.tsx @@ -3,20 +3,17 @@ import { ComponentPropsWithoutRef, ElementType, ReactNode } from 'react' import s from './button.module.scss' export type ButtonProps = { - as?: T - children: ReactNode - className?: string - fullWidth?: boolean - variant?: 'icon' | 'link' | 'primary' | 'secondary' | 'tertiary' + as?: T + children: ReactNode + className?: string + fullWidth?: boolean + variant?: 'icon' | 'link' | 'primary' | 'secondary' | 'tertiary' } & ComponentPropsWithoutRef export const Button = (props: ButtonProps) => { - const { as: Component = 'button', className, fullWidth, variant = 'primary', ...rest } = props + const { as: Component = 'button', className, fullWidth, variant = 'primary', ...rest } = props - return ( - - ) + return ( + + ) } diff --git a/src/components/ui/card/card.stories.tsx b/src/components/ui/card/card.stories.tsx index d9e6f39..04f9afc 100644 --- a/src/components/ui/card/card.stories.tsx +++ b/src/components/ui/card/card.stories.tsx @@ -4,21 +4,21 @@ import { Card } from './' import { Typography } from '@/components' const meta = { - component: Card, - tags: ['autodocs'], - title: 'Components/Card', + component: Card, + tags: ['autodocs'], + title: 'Components/Card', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - children: Card, - style: { - height: '300px', - padding: '24px', - width: '300px', - }, + args: { + children: Card, + style: { + height: '300px', + padding: '24px', + width: '300px', }, + }, } diff --git a/src/components/ui/card/card.tsx b/src/components/ui/card/card.tsx index 8ca91e3..4302c10 100644 --- a/src/components/ui/card/card.tsx +++ b/src/components/ui/card/card.tsx @@ -7,9 +7,9 @@ import s from './card.module.scss' export type CardProps = {} & ComponentPropsWithoutRef<'div'> export const Card = forwardRef(({ className, ...restProps }, ref) => { - const classNames = { - root: clsx(s.root, className), - } + const classNames = { + root: clsx(s.root, className), + } - return + return }) diff --git a/src/components/ui/checkbox/checkbox.stories.tsx b/src/components/ui/checkbox/checkbox.stories.tsx index 9fa869c..6e50671 100644 --- a/src/components/ui/checkbox/checkbox.stories.tsx +++ b/src/components/ui/checkbox/checkbox.stories.tsx @@ -3,32 +3,32 @@ import { useState } from 'react' import { Checkbox } from './checkbox' import { Meta, StoryObj } from '@storybook/react' const meta = { - component: Checkbox, - tags: ['autodocs'], - title: 'Components/Checkbox', + component: Checkbox, + tags: ['autodocs'], + title: 'Components/Checkbox', } satisfies Meta export default meta type Story = StoryObj export const Uncontrolled: Story = { - args: { - disabled: false, - label: 'Click here', - }, + args: { + disabled: false, + label: 'Click here', + }, } export const Controlled: Story = { - render: args => { - const [checked, setChecked] = useState(false) + render: args => { + const [checked, setChecked] = useState(false) - return ( - setChecked(!checked)} - /> - ) - }, + return ( + setChecked(!checked)} + /> + ) + }, } diff --git a/src/components/ui/checkbox/checkbox.tsx b/src/components/ui/checkbox/checkbox.tsx index 8a2058e..58439de 100644 --- a/src/components/ui/checkbox/checkbox.tsx +++ b/src/components/ui/checkbox/checkbox.tsx @@ -9,60 +9,57 @@ import { clsx } from 'clsx' import s from './checkbox.module.scss' export type CheckboxProps = { - checked?: boolean - className?: string - disabled?: boolean - id?: string - label?: string - onChange?: (checked: boolean) => void - position?: 'left' - required?: boolean + checked?: boolean + className?: string + disabled?: boolean + id?: string + label?: string + onChange?: (checked: boolean) => void + position?: 'left' + required?: boolean } export const Checkbox: FC = ({ - checked, - className, - disabled, - id, - label, - onChange, - position, - required, + checked, + className, + disabled, + id, + label, + onChange, + position, + required, }) => { - const classNames = { - buttonWrapper: clsx(s.buttonWrapper, disabled && s.disabled, position === 'left' && s.left), - container: clsx(s.container, className), - indicator: s.indicator, - label: clsx(s.label, disabled && s.disabled), - root: s.root, - } + const classNames = { + buttonWrapper: clsx(s.buttonWrapper, disabled && s.disabled, position === 'left' && s.left), + container: clsx(s.container, className), + indicator: s.indicator, + label: clsx(s.label, disabled && s.disabled), + root: s.root, + } - return ( - - - - - - {checked && ( - - - - )} - - - {label} - - - - ) + return ( + + + + + + {checked && ( + + + + )} + + + {label} + + + + ) } diff --git a/src/components/ui/controlled/controlled-checkbox/controlled-checkbox.tsx b/src/components/ui/controlled/controlled-checkbox/controlled-checkbox.tsx index 95eb77c..cc7212a 100644 --- a/src/components/ui/controlled/controlled-checkbox/controlled-checkbox.tsx +++ b/src/components/ui/controlled/controlled-checkbox/controlled-checkbox.tsx @@ -3,34 +3,34 @@ import { FieldValues, UseControllerProps, useController } from 'react-hook-form' import { Checkbox, CheckboxProps } from '../../' export type ControlledCheckboxProps = - UseControllerProps & Omit + UseControllerProps & Omit export const ControlledCheckbox = ({ + control, + defaultValue, + name, + rules, + shouldUnregister, + ...checkboxProps +}: ControlledCheckboxProps) => { + const { + field: { onChange, value }, + } = useController({ control, defaultValue, name, rules, shouldUnregister, - ...checkboxProps -}: ControlledCheckboxProps) => { - const { - field: { onChange, value }, - } = useController({ - control, - defaultValue, - name, - rules, - shouldUnregister, - }) + }) - return ( - - ) + return ( + + ) } diff --git a/src/components/ui/controlled/controlled-radio-group/controlled-radio-group.tsx b/src/components/ui/controlled/controlled-radio-group/controlled-radio-group.tsx index ed571f5..d20d761 100644 --- a/src/components/ui/controlled/controlled-radio-group/controlled-radio-group.tsx +++ b/src/components/ui/controlled/controlled-radio-group/controlled-radio-group.tsx @@ -3,28 +3,28 @@ import { Control, FieldPath, FieldValues, useController } from 'react-hook-form' import { RadioGroup, RadioGroupProps } from '@/components/ui' export type ControlledRadioGroupProps = { - control: Control - name: FieldPath + control: Control + name: FieldPath } & Omit export const ControlledRadioGroup = ( - props: ControlledRadioGroupProps + props: ControlledRadioGroupProps ) => { - const { - field: { onChange, ...field }, - fieldState: { error }, - } = useController({ - control: props.control, - name: props.name, - }) + const { + field: { onChange, ...field }, + fieldState: { error }, + } = useController({ + control: props.control, + name: props.name, + }) - return ( - - ) + return ( + + ) } diff --git a/src/components/ui/controlled/controlled-text-field/controlled-text-field.tsx b/src/components/ui/controlled/controlled-text-field/controlled-text-field.tsx index 3a70ed3..707ed09 100644 --- a/src/components/ui/controlled/controlled-text-field/controlled-text-field.tsx +++ b/src/components/ui/controlled/controlled-text-field/controlled-text-field.tsx @@ -3,20 +3,20 @@ import { Control, FieldPath, FieldValues, useController } from 'react-hook-form' import { TextField, TextFieldProps } from '@/components' export type ControlledTextFieldProps = { - control: Control - name: FieldPath + control: Control + name: FieldPath } & Omit export const ControlledTextField = ( - props: ControlledTextFieldProps + props: ControlledTextFieldProps ) => { - const { - field, - fieldState: { error }, - } = useController({ - control: props.control, - name: props.name, - }) + const { + field, + fieldState: { error }, + } = useController({ + control: props.control, + name: props.name, + }) - return + return } diff --git a/src/components/ui/dialog/dialog.stories.tsx b/src/components/ui/dialog/dialog.stories.tsx index 0e75eac..854d88f 100644 --- a/src/components/ui/dialog/dialog.stories.tsx +++ b/src/components/ui/dialog/dialog.stories.tsx @@ -4,31 +4,31 @@ import { Dialog } from './' import { Meta, StoryObj } from '@storybook/react' const meta = { - component: Dialog, - tags: ['autodocs'], - title: 'Components/Dialog', + component: Dialog, + tags: ['autodocs'], + title: 'Components/Dialog', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - children: 'Modal', - onOpenChange: () => {}, - open: true, - title: 'Modal', - }, - render: args => { - const [open, setOpen] = useState(false) + args: { + children: 'Modal', + onOpenChange: () => {}, + open: true, + title: 'Modal', + }, + render: args => { + const [open, setOpen] = useState(false) - return ( - <> - setOpen(true)}>Open Modal - - Dialog content here - - > - ) - }, + return ( + <> + setOpen(true)}>Open Modal + + Dialog content here + + > + ) + }, } diff --git a/src/components/ui/dialog/dialog.tsx b/src/components/ui/dialog/dialog.tsx index e75685a..ea180bd 100644 --- a/src/components/ui/dialog/dialog.tsx +++ b/src/components/ui/dialog/dialog.tsx @@ -3,28 +3,28 @@ import { Button, Modal, ModalProps } from '@/components' import s from './dialog.module.scss' export type DialogProps = ModalProps & { - cancelText?: string - confirmText?: string - onCancel?: () => void - onConfirm?: () => void + cancelText?: string + confirmText?: string + onCancel?: () => void + onConfirm?: () => void } export const Dialog = ({ - cancelText = 'Cancel', - children, - confirmText = 'OK', - onCancel, - onConfirm, - ...modalProps + cancelText = 'Cancel', + children, + confirmText = 'OK', + onCancel, + onConfirm, + ...modalProps }: DialogProps) => { - return ( - - {children} - - - {cancelText} - - {confirmText} - - - ) + return ( + + {children} + + + {cancelText} + + {confirmText} + + + ) } diff --git a/src/components/ui/label/label.tsx b/src/components/ui/label/label.tsx index 54f39d6..ae33c9a 100644 --- a/src/components/ui/label/label.tsx +++ b/src/components/ui/label/label.tsx @@ -6,18 +6,18 @@ import { clsx } from 'clsx' import s from './label.module.scss' export type LabelProps = { - label?: ReactNode + label?: ReactNode } & ComponentPropsWithoutRef<'label'> export const Label: FC = ({ children, className, label, ...rest }) => { - const classNames = { - label: clsx(s.label, className), - } + const classNames = { + label: clsx(s.label, className), + } - return ( - - {label && {label}} - {children} - - ) + return ( + + {label && {label}} + {children} + + ) } diff --git a/src/components/ui/modal/modal.stories.tsx b/src/components/ui/modal/modal.stories.tsx index fe717d8..3bd532e 100644 --- a/src/components/ui/modal/modal.stories.tsx +++ b/src/components/ui/modal/modal.stories.tsx @@ -4,31 +4,31 @@ import { Modal } from '@/components' import { Meta, StoryObj } from '@storybook/react' const meta = { - component: Modal, - tags: ['autodocs'], - title: 'Components/Modal', + component: Modal, + tags: ['autodocs'], + title: 'Components/Modal', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - children: 'Modal', - onOpenChange: () => {}, - open: true, - title: 'Modal', - }, - render: args => { - const [open, setOpen] = useState(false) + args: { + children: 'Modal', + onOpenChange: () => {}, + open: true, + title: 'Modal', + }, + render: args => { + const [open, setOpen] = useState(false) - return ( - <> - setOpen(true)}>Open Modal - - Modal content here - - > - ) - }, + return ( + <> + setOpen(true)}>Open Modal + + Modal content here + + > + ) + }, } diff --git a/src/components/ui/modal/modal.tsx b/src/components/ui/modal/modal.tsx index e2d08a4..80016d9 100644 --- a/src/components/ui/modal/modal.tsx +++ b/src/components/ui/modal/modal.tsx @@ -7,30 +7,30 @@ import * as DialogPrimitive from '@radix-ui/react-dialog' import s from './modal.module.scss' export type ModalProps = { - children: ReactNode - onOpenChange: (open: boolean) => void - open: boolean - title?: string + children: ReactNode + onOpenChange: (open: boolean) => void + open: boolean + title?: string } & Omit, 'onOpenChange' | 'open'> export const Modal = ({ children, title, ...props }: ModalProps) => { - return ( - - - - - - - - {title} - - - - - - - {children} - - - - ) + return ( + + + + + + + + {title} + + + + + + + {children} + + + + ) } diff --git a/src/components/ui/page/page.tsx b/src/components/ui/page/page.tsx index 1796c68..5805a6f 100644 --- a/src/components/ui/page/page.tsx +++ b/src/components/ui/page/page.tsx @@ -7,9 +7,9 @@ import s from './page.module.scss' export type PageProps = ComponentPropsWithoutRef<'div'> export const Page = forwardRef(({ className, ...props }, ref) => { - const classNames = { - root: clsx(s.root, className), - } + const classNames = { + root: clsx(s.root, className), + } - return + return }) diff --git a/src/components/ui/pagination/pagination.tsx b/src/components/ui/pagination/pagination.tsx index 2738591..eab5115 100644 --- a/src/components/ui/pagination/pagination.tsx +++ b/src/components/ui/pagination/pagination.tsx @@ -7,194 +7,187 @@ import { clsx } from 'clsx' import s from './pagination.module.scss' type PaginationConditionals = - | { - onPerPageChange: (itemPerPage: number) => void - perPage: number - perPageOptions: number[] - } - | { - onPerPageChange?: never - perPage?: null - perPageOptions?: never - } + | { + onPerPageChange: (itemPerPage: number) => void + perPage: number + perPageOptions: number[] + } + | { + onPerPageChange?: never + perPage?: null + perPageOptions?: never + } export type PaginationProps = { - count: number - onChange: (page: number) => void - onPerPageChange?: (itemPerPage: number) => void - page: number - perPage?: number - perPageOptions?: number[] - siblings?: number + count: number + onChange: (page: number) => void + onPerPageChange?: (itemPerPage: number) => void + page: number + perPage?: number + perPageOptions?: number[] + siblings?: number } & PaginationConditionals const classNames = { - container: s.container, - dots: s.dots, - icon: s.icon, - item: s.item, - pageButton(selected?: boolean) { - return clsx(this.item, selected && s.selected) - }, - root: s.root, - select: s.select, - selectBox: s.selectBox, + container: s.container, + dots: s.dots, + icon: s.icon, + item: s.item, + pageButton(selected?: boolean) { + return clsx(this.item, selected && s.selected) + }, + root: s.root, + select: s.select, + selectBox: s.selectBox, } export const Pagination: FC = ({ + count, + onChange, + onPerPageChange, + page, + perPage = null, + perPageOptions, + siblings, +}) => { + const { + handleMainPageClicked, + handleNextPageClicked, + handlePreviousPageClicked, + isFirstPage, + isLastPage, + paginationRange, + } = usePagination({ count, onChange, - onPerPageChange, page, - perPage = null, - perPageOptions, siblings, -}) => { - const { - handleMainPageClicked, - handleNextPageClicked, - handlePreviousPageClicked, - isFirstPage, - isLastPage, - paginationRange, - } = usePagination({ - count, - onChange, - page, - siblings, - }) + }) - const showPerPageSelect = !!perPage && !!perPageOptions && !!onPerPageChange + const showPerPageSelect = !!perPage && !!perPageOptions && !!onPerPageChange - return ( - - - + return ( + + + - + - - + + - {showPerPageSelect && ( - - )} - - ) + {showPerPageSelect && ( + + )} + + ) } type NavigationButtonProps = { - disabled?: boolean - onClick: () => void + disabled?: boolean + onClick: () => void } type PageButtonProps = NavigationButtonProps & { - page: number - selected: boolean + page: number + selected: boolean } const Dots: FC = () => { - return … + return … } const PageButton: FC = ({ disabled, onClick, page, selected }) => { - return ( - - {page} - - ) + return ( + + {page} + + ) } const PrevButton: FC = ({ disabled, onClick }) => { - return ( - - - - ) + return ( + + + + ) } const NextButton: FC = ({ disabled, onClick }) => { - return ( - - - - ) + return ( + + + + ) } type MainPaginationButtonsProps = { - currentPage: number - onClick: (pageNumber: number) => () => void - paginationRange: (number | string)[] + currentPage: number + onClick: (pageNumber: number) => () => void + paginationRange: (number | string)[] } const MainPaginationButtons: FC = ({ - currentPage, - onClick, - paginationRange, + currentPage, + onClick, + paginationRange, }) => { - return ( - <> - {paginationRange.map((page: number | string, index) => { - const isSelected = page === currentPage + return ( + <> + {paginationRange.map((page: number | string, index) => { + const isSelected = page === currentPage - if (typeof page !== 'number') { - return - } + if (typeof page !== 'number') { + return + } - return ( - - ) - })} - > - ) + return + })} + > + ) } export type PerPageSelectProps = { - onPerPageChange: (itemPerPage: number) => void - perPage: number - perPageOptions: number[] + onPerPageChange: (itemPerPage: number) => void + perPage: number + perPageOptions: number[] } export const PerPageSelect: FC = ( - { - // perPage, - // perPageOptions, - // onPerPageChange, - } + { + // perPage, + // perPageOptions, + // onPerPageChange, + } ) => { - // const selectOptions = perPageOptions.map(value => ({ - // label: value, - // value, - // })) + // const selectOptions = perPageOptions.map(value => ({ + // label: value, + // value, + // })) - return ( - - Показать - {/**/} - на странице - - ) + return ( + + Показать + {/**/} + на странице + + ) } diff --git a/src/components/ui/pagination/usePagination.ts b/src/components/ui/pagination/usePagination.ts index 98fa57b..be7d78e 100644 --- a/src/components/ui/pagination/usePagination.ts +++ b/src/components/ui/pagination/usePagination.ts @@ -3,110 +3,110 @@ import { useCallback, useMemo } from 'react' // original code: https://www.freecodecamp.org/news/build-a-custom-pagination-component-in-react/ const range = (start: number, end: number) => { - const length = end - start + 1 + const length = end - start + 1 - /* + /* Create an array of certain length and set the elements within it from start value to end value. */ - return Array.from({ length }, (_, idx) => idx + start) + return Array.from({ length }, (_, idx) => idx + start) } const DOTS = '...' type UsePaginationParamType = { - count: number - onChange: (pageNumber: number) => void - page: number - siblings?: number + count: number + onChange: (pageNumber: number) => void + page: number + siblings?: number } type PaginationRange = ('...' | number)[] export const usePagination = ({ count, onChange, page, siblings = 1 }: UsePaginationParamType) => { - const paginationRange = useMemo(() => { - // Pages count is determined as siblingCount + firstPage + lastPage + page + 2*DOTS - const totalPageNumbers = siblings + 5 + const paginationRange = useMemo(() => { + // Pages count is determined as siblingCount + firstPage + lastPage + page + 2*DOTS + const totalPageNumbers = siblings + 5 - /* + /* Case 1: If the number of pages is less than the page numbers we want to show in our paginationComponent, we return the range [1..totalPageCount] */ - if (totalPageNumbers >= count) { - return range(1, count) - } + if (totalPageNumbers >= count) { + return range(1, count) + } - /* + /* Calculate left and right sibling index and make sure they are within range 1 and totalPageCount */ - const leftSiblingIndex = Math.max(page - siblings, 1) - const rightSiblingIndex = Math.min(page + siblings, count) + const leftSiblingIndex = Math.max(page - siblings, 1) + const rightSiblingIndex = Math.min(page + siblings, count) - /* + /* We do not show dots when there is only one page number to be inserted between the extremes of siblings and the page limits i.e 1 and totalPageCount. Hence, we are using leftSiblingIndex > 2 and rightSiblingIndex < totalPageCount - 2 */ - const shouldShowLeftDots = leftSiblingIndex > 2 - const shouldShowRightDots = rightSiblingIndex < count - 2 + const shouldShowLeftDots = leftSiblingIndex > 2 + const shouldShowRightDots = rightSiblingIndex < count - 2 - const firstPageIndex = 1 - const lastPageIndex = count + const firstPageIndex = 1 + const lastPageIndex = count - /* + /* Case 2: No left dots to show, but rights dots to be shown */ - if (!shouldShowLeftDots && shouldShowRightDots) { - const leftItemCount = 3 + 2 * siblings - const leftRange = range(1, leftItemCount) + if (!shouldShowLeftDots && shouldShowRightDots) { + const leftItemCount = 3 + 2 * siblings + const leftRange = range(1, leftItemCount) - return [...leftRange, DOTS, count] - } + return [...leftRange, DOTS, count] + } - /* + /* Case 3: No right dots to show, but left dots to be shown */ - if (shouldShowLeftDots && !shouldShowRightDots) { - const rightItemCount = 3 + 2 * siblings - const rightRange = range(count - rightItemCount + 1, count) + if (shouldShowLeftDots && !shouldShowRightDots) { + const rightItemCount = 3 + 2 * siblings + const rightRange = range(count - rightItemCount + 1, count) - return [firstPageIndex, DOTS, ...rightRange] - } + return [firstPageIndex, DOTS, ...rightRange] + } - /* + /* Case 4: Both left and right dots to be shown */ - if (shouldShowLeftDots && shouldShowRightDots) { - const middleRange = range(leftSiblingIndex, rightSiblingIndex) + if (shouldShowLeftDots && shouldShowRightDots) { + const middleRange = range(leftSiblingIndex, rightSiblingIndex) - return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex] - } - }, [siblings, page, count]) as PaginationRange - - const lastPage = paginationRange.at(-1) - - const isFirstPage = page === 1 - const isLastPage = page === lastPage - - const handleNextPageClicked = useCallback(() => { - onChange(page + 1) - }, [page, onChange]) - - const handlePreviousPageClicked = useCallback(() => { - onChange(page - 1) - }, [page, onChange]) - - function handleMainPageClicked(pageNumber: number) { - return () => onChange(pageNumber) + return [firstPageIndex, DOTS, ...middleRange, DOTS, lastPageIndex] } + }, [siblings, page, count]) as PaginationRange - return { - handleMainPageClicked, - handleNextPageClicked, - handlePreviousPageClicked, - isFirstPage, - isLastPage, - paginationRange, - } + const lastPage = paginationRange.at(-1) + + const isFirstPage = page === 1 + const isLastPage = page === lastPage + + const handleNextPageClicked = useCallback(() => { + onChange(page + 1) + }, [page, onChange]) + + const handlePreviousPageClicked = useCallback(() => { + onChange(page - 1) + }, [page, onChange]) + + function handleMainPageClicked(pageNumber: number) { + return () => onChange(pageNumber) + } + + return { + handleMainPageClicked, + handleNextPageClicked, + handlePreviousPageClicked, + isFirstPage, + isLastPage, + paginationRange, + } } diff --git a/src/components/ui/radio-group/radio-group.stories.tsx b/src/components/ui/radio-group/radio-group.stories.tsx index b326525..4b9011f 100644 --- a/src/components/ui/radio-group/radio-group.stories.tsx +++ b/src/components/ui/radio-group/radio-group.stories.tsx @@ -3,29 +3,29 @@ import type { Meta, StoryObj } from '@storybook/react' import { RadioGroup } from './' const meta = { - component: RadioGroup, - tags: ['autodocs'], - title: 'Components/Radio Group', + component: RadioGroup, + tags: ['autodocs'], + title: 'Components/Radio Group', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - options: [ - { label: 'Option One', value: 'option-one' }, - { label: 'Option Two', value: 'option-two' }, - ], - }, + args: { + options: [ + { label: 'Option One', value: 'option-one' }, + { label: 'Option Two', value: 'option-two' }, + ], + }, } export const Disabled: Story = { - args: { - disabled: true, - options: [ - { label: 'Option One', value: 'option-one' }, - { label: 'Option Two', value: 'option-two' }, - ], - }, + args: { + disabled: true, + options: [ + { label: 'Option One', value: 'option-one' }, + { label: 'Option Two', value: 'option-two' }, + ], + }, } diff --git a/src/components/ui/radio-group/radio-group.tsx b/src/components/ui/radio-group/radio-group.tsx index f5677aa..8941f76 100644 --- a/src/components/ui/radio-group/radio-group.tsx +++ b/src/components/ui/radio-group/radio-group.tsx @@ -7,56 +7,56 @@ import { clsx } from 'clsx' import s from './radio-group.module.scss' const RadioGroupRoot = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ className, ...props }, ref) => { - return + return }) RadioGroupRoot.displayName = RadioGroupPrimitive.Root.displayName const RadioGroupItem = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef + React.ElementRef, + React.ComponentPropsWithoutRef >(({ children, className, ...props }, ref) => { - return ( - - - - ) + return ( + + + + ) }) RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName type Option = { - label: string - value: string + label: string + value: string } export type RadioGroupProps = Omit< - React.ComponentPropsWithoutRef, - 'children' + React.ComponentPropsWithoutRef, + 'children' > & { - errorMessage?: string - options: Option[] + errorMessage?: string + options: Option[] } const RadioGroup = React.forwardRef< - React.ElementRef, - RadioGroupProps + React.ElementRef, + RadioGroupProps >((props, ref) => { - const { errorMessage, options, ...restProps } = props + const { errorMessage, options, ...restProps } = props - return ( - - {options.map(option => ( - - - - {option.label} - - - ))} - - ) + return ( + + {options.map(option => ( + + + + {option.label} + + + ))} + + ) }) export { RadioGroup, RadioGroupItem, RadioGroupRoot } diff --git a/src/components/ui/slider/slider.tsx b/src/components/ui/slider/slider.tsx index 7125d82..99d7ebe 100644 --- a/src/components/ui/slider/slider.tsx +++ b/src/components/ui/slider/slider.tsx @@ -5,37 +5,37 @@ import { clsx } from 'clsx' import s from './slider.module.scss' const Slider = forwardRef< - ElementRef, - Omit, 'value'> & { - value?: (number | undefined)[] - } + ElementRef, + Omit, 'value'> & { + value?: (number | undefined)[] + } >(({ className, max, onValueChange, value, ...props }, ref) => { - useEffect(() => { - if (value?.[1] === undefined || value?.[1] === null) { - onValueChange?.([value?.[0] ?? 0, max ?? 0]) - } - }, [max, value, onValueChange]) + useEffect(() => { + if (value?.[1] === undefined || value?.[1] === null) { + onValueChange?.([value?.[0] ?? 0, max ?? 0]) + } + }, [max, value, onValueChange]) - return ( - - {value?.[0]} - - - - - - - - {value?.[1]} - - ) + return ( + + {value?.[0]} + + + + + + + + {value?.[1]} + + ) }) Slider.displayName = SliderPrimitive.Root.displayName diff --git a/src/components/ui/table/table.stories.tsx b/src/components/ui/table/table.stories.tsx index afd7204..9ea1833 100644 --- a/src/components/ui/table/table.stories.tsx +++ b/src/components/ui/table/table.stories.tsx @@ -3,127 +3,124 @@ import { Typography } from '@/components' import { Meta } from '@storybook/react' export default { - component: Table, - title: 'Components/Table', + component: Table, + title: 'Components/Table', } as Meta export const Default = { - args: { - children: ( - <> - - - Название - Описание - Ссылка - Тип - Вид - - - - - - Web Basic - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod - tempor incididunt ut sed do eiusmod tempoei usmodr sit amet, consectetur - adipiscing elit, sed do... - - - - Какая-то ссылка кудато на какой-то источник с информациейо ссылка - кудато на какой-то источник - - - Основной - Читать - 🦎 - - - Web Basic - - Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod - tempor incididunt ut sed do eiusmod tempoei usmodr sit amet, consectetur - adipiscing elit, sed do... - - - Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато - на какой-то источник - - Основной - Читать - ✨ - - - > - ), - }, + args: { + children: ( + <> + + + Название + Описание + Ссылка + Тип + Вид + + + + + + Web Basic + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + incididunt ut sed do eiusmod tempoei usmodr sit amet, consectetur adipiscing elit, sed + do... + + + + Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то + источник + + + Основной + Читать + 🦎 + + + Web Basic + + Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + incididunt ut sed do eiusmod tempoei usmodr sit amet, consectetur adipiscing elit, sed + do... + + + Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то + источник + + Основной + Читать + ✨ + + + > + ), + }, } const data = [ - { - category: 'Основной', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', - id: '01', - link: 'Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то', - title: 'Web Basic', - type: 'Читать', - }, - { - category: 'Основной', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', - id: '02', - link: 'Какая-то ссылка куда-то', - title: 'Web Basic', - type: 'Читать', - }, - { - category: 'Основной', - description: - 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', - id: '03', - link: 'Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то. Какая-то ссылка кудато на какой-то источник с информациейо ссылка куда-то на какой-то', - title: 'Web Basic', - type: 'Читать', - }, + { + category: 'Основной', + description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', + id: '01', + link: 'Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то', + title: 'Web Basic', + type: 'Читать', + }, + { + category: 'Основной', + description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', + id: '02', + link: 'Какая-то ссылка куда-то', + title: 'Web Basic', + type: 'Читать', + }, + { + category: 'Основной', + description: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor', + id: '03', + link: 'Какая-то ссылка кудато на какой-то источник с информациейо ссылка кудато на какой-то. Какая-то ссылка кудато на какой-то источник с информациейо ссылка куда-то на какой-то', + title: 'Web Basic', + type: 'Читать', + }, ] export const WithMapMethod = { - args: { - children: ( - <> - - - Название - Описание - Ссылка - Тип - Вид - - - - {data.map(item => ( - - {item.title} - {item.description} - {item.link} - {item.category} - {item.type} - - ))} - - > - ), - }, + args: { + children: ( + <> + + + Название + Описание + Ссылка + Тип + Вид + + + + {data.map(item => ( + + {item.title} + {item.description} + {item.link} + {item.category} + {item.type} + + ))} + + > + ), + }, } export const Empty = { - render: () => , + render: () => , } diff --git a/src/components/ui/table/table.tsx b/src/components/ui/table/table.tsx index 57dd4cc..cea4a58 100644 --- a/src/components/ui/table/table.tsx +++ b/src/components/ui/table/table.tsx @@ -6,125 +6,123 @@ import { clsx } from 'clsx' import s from './table.module.scss' export const Table = forwardRef>( - ({ className, ...rest }, ref) => { - const classNames = { - table: clsx(className, s.table), - } - - return + ({ className, ...rest }, ref) => { + const classNames = { + table: clsx(className, s.table), } + + return + } ) export const TableHead = forwardRef, ComponentPropsWithoutRef<'thead'>>( - ({ ...rest }, ref) => { - return - } + ({ ...rest }, ref) => { + return + } ) export const TableBody = forwardRef, ComponentPropsWithoutRef<'tbody'>>( - ({ ...rest }, ref) => { - return - } + ({ ...rest }, ref) => { + return + } ) export const TableRow = forwardRef, ComponentPropsWithoutRef<'tr'>>( - ({ ...rest }, ref) => { - return - } + ({ ...rest }, ref) => { + return + } ) export const TableHeadCell = forwardRef, ComponentPropsWithoutRef<'th'>>( - ({ children, className, ...rest }, ref) => { - const classNames = { - headCell: clsx(className, s.headCell), - } - - return ( - - {children} - - ) + ({ children, className, ...rest }, ref) => { + const classNames = { + headCell: clsx(className, s.headCell), } + + return ( + + {children} + + ) + } ) export const TableCell = forwardRef, ComponentPropsWithoutRef<'td'>>( - ({ className, ...rest }, ref) => { - const classNames = { - cell: clsx(className, s.tableCell), - } - - return + ({ className, ...rest }, ref) => { + const classNames = { + cell: clsx(className, s.tableCell), } + + return + } ) export const TableEmpty: FC & { mb?: string; mt?: string }> = ({ - className, - mb, - mt = '89px', + className, + mb, + mt = '89px', }) => { - const classNames = { - empty: clsx(className, s.empty), - } + const classNames = { + empty: clsx(className, s.empty), + } - return ( - - Пока тут еще нет данных! :( - - ) + return ( + + Пока тут еще нет данных! :( + + ) } export type Column = { - key: string - sortable?: boolean - title: string + key: string + sortable?: boolean + title: string } export type Sort = { - direction: 'asc' | 'desc' - key: string + direction: 'asc' | 'desc' + key: string } | null export const TableHeader: FC< - Omit< - ComponentPropsWithoutRef<'thead'> & { - columns: Column[] - onSort?: (sort: Sort) => void - sort?: Sort - }, - 'children' - > + Omit< + ComponentPropsWithoutRef<'thead'> & { + columns: Column[] + onSort?: (sort: Sort) => void + sort?: Sort + }, + 'children' + > > = ({ columns, onSort, sort, ...restProps }) => { - const handleSort = (key: string, sortable?: boolean) => () => { - if (!onSort || !sortable) { - return - } - - if (sort?.key !== key) { - return onSort({ direction: 'asc', key }) - } - - if (sort.direction === 'desc') { - return onSort(null) - } - - return onSort({ - direction: sort?.direction === 'asc' ? 'desc' : 'asc', - key, - }) + const handleSort = (key: string, sortable?: boolean) => () => { + if (!onSort || !sortable) { + return } - return ( - - - {columns.map(({ key, sortable = true, title }) => ( - - {title} - {sort && sort.key === key && ( - {sort.direction === 'asc' ? '▲' : '▼'} - )} - - ))} - - - ) + if (sort?.key !== key) { + return onSort({ direction: 'asc', key }) + } + + if (sort.direction === 'desc') { + return onSort(null) + } + + return onSort({ + direction: sort?.direction === 'asc' ? 'desc' : 'asc', + key, + }) + } + + return ( + + + {columns.map(({ key, sortable = true, title }) => ( + + {title} + {sort && sort.key === key && {sort.direction === 'asc' ? '▲' : '▼'}} + + ))} + + + ) } diff --git a/src/components/ui/tabs/tabs.tsx b/src/components/ui/tabs/tabs.tsx index 305962b..d4c909e 100644 --- a/src/components/ui/tabs/tabs.tsx +++ b/src/components/ui/tabs/tabs.tsx @@ -8,28 +8,28 @@ import s from './tabs.module.scss' const Tabs = TabsPrimitive.Root const TabsList = forwardRef< - ElementRef, - ComponentPropsWithoutRef + ElementRef, + ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) TabsList.displayName = TabsPrimitive.List.displayName const TabsTrigger = forwardRef< - ElementRef, - ComponentPropsWithoutRef + ElementRef, + ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) TabsTrigger.displayName = TabsPrimitive.Trigger.displayName const TabsContent = forwardRef< - ElementRef, - ComponentPropsWithoutRef + ElementRef, + ComponentPropsWithoutRef >(({ className, ...props }, ref) => ( - + )) TabsContent.displayName = TabsPrimitive.Content.displayName diff --git a/src/components/ui/text-field/text-field.stories.ts b/src/components/ui/text-field/text-field.stories.ts index 3a8c06d..00c5e72 100644 --- a/src/components/ui/text-field/text-field.stories.ts +++ b/src/components/ui/text-field/text-field.stories.ts @@ -3,33 +3,33 @@ import type { Meta, StoryObj } from '@storybook/react' import { TextField } from './' const meta = { - component: TextField, - tags: ['autodocs'], - title: 'Components/TextField', + component: TextField, + tags: ['autodocs'], + title: 'Components/TextField', } satisfies Meta export default meta type Story = StoryObj export const Default: Story = { - args: { - label: 'Label', - placeholder: 'Placeholder', - }, + args: { + label: 'Label', + placeholder: 'Placeholder', + }, } export const Password: Story = { - args: { - label: 'Label', - placeholder: 'Password', - type: 'password', - }, + args: { + label: 'Label', + placeholder: 'Password', + type: 'password', + }, } export const Error: Story = { - args: { - errorMessage: 'Error message', - label: 'Input with error', - value: 'Wrong value', - }, + args: { + errorMessage: 'Error message', + label: 'Input with error', + value: 'Wrong value', + }, } diff --git a/src/components/ui/text-field/text-field.tsx b/src/components/ui/text-field/text-field.tsx index 937dd1b..b7a9cce 100644 --- a/src/components/ui/text-field/text-field.tsx +++ b/src/components/ui/text-field/text-field.tsx @@ -7,91 +7,91 @@ import { clsx } from 'clsx' import s from './text-field.module.scss' export type TextFieldProps = { - containerProps?: ComponentProps<'div'> - errorMessage?: string - label?: string - labelProps?: ComponentProps<'label'> - onValueChange?: (value: string) => void - search?: boolean + containerProps?: ComponentProps<'div'> + errorMessage?: string + label?: string + labelProps?: ComponentProps<'label'> + onValueChange?: (value: string) => void + search?: boolean } & ComponentPropsWithoutRef<'input'> export const TextField = forwardRef( - ( - { - className, - containerProps, - errorMessage, - label, - labelProps, - onChange, - onValueChange, - placeholder, - search, - type, - ...restProps - }, - ref - ) => { - const [showPassword, setShowPassword] = useState(false) + ( + { + className, + containerProps, + errorMessage, + label, + labelProps, + onChange, + onValueChange, + placeholder, + search, + type, + ...restProps + }, + ref + ) => { + const [showPassword, setShowPassword] = useState(false) - const isShowPasswordButtonShown = type === 'password' + const isShowPasswordButtonShown = type === 'password' - const finalType = getFinalType(type, showPassword) + const finalType = getFinalType(type, showPassword) - function handleChange(e: ChangeEvent) { - onChange?.(e) - onValueChange?.(e.target.value) - } - - const classNames = { - error: clsx(s.error), - field: clsx(s.field, !!errorMessage && s.error, search && s.hasLeadingIcon, className), - fieldContainer: clsx(s.fieldContainer), - label: clsx(s.label, labelProps?.className), - leadingIcon: s.leadingIcon, - root: clsx(s.root, containerProps?.className), - } - - return ( - - {label && ( - - {label} - - )} - - {search && } - - {isShowPasswordButtonShown && ( - setShowPassword(prev => !prev)} - type={'button'} - > - {showPassword ? : } - - )} - - - - {errorMessage} - - - ) + function handleChange(e: ChangeEvent) { + onChange?.(e) + onValueChange?.(e.target.value) } + + const classNames = { + error: clsx(s.error), + field: clsx(s.field, !!errorMessage && s.error, search && s.hasLeadingIcon, className), + fieldContainer: clsx(s.fieldContainer), + label: clsx(s.label, labelProps?.className), + leadingIcon: s.leadingIcon, + root: clsx(s.root, containerProps?.className), + } + + return ( + + {label && ( + + {label} + + )} + + {search && } + + {isShowPasswordButtonShown && ( + setShowPassword(prev => !prev)} + type={'button'} + > + {showPassword ? : } + + )} + + + + {errorMessage} + + + ) + } ) function getFinalType(type: ComponentProps<'input'>['type'], showPassword: boolean) { - if (type === 'password' && showPassword) { - return 'text' - } + if (type === 'password' && showPassword) { + return 'text' + } - return type + return type } diff --git a/src/components/ui/typography/typography.stories.tsx b/src/components/ui/typography/typography.stories.tsx index 2c4b9aa..12e9847 100644 --- a/src/components/ui/typography/typography.stories.tsx +++ b/src/components/ui/typography/typography.stories.tsx @@ -3,121 +3,121 @@ import type { Meta, StoryObj } from '@storybook/react' import { Typography } from './' const meta = { - argTypes: { - variant: { - control: { type: 'radio' }, - options: [ - 'large', - 'h1', - 'h2', - 'h3', - 'body1', - 'body2', - 'subtitle1', - 'subtitle2', - 'caption', - 'overline', - 'link1', - 'link2', - 'error', - ], - }, + argTypes: { + variant: { + control: { type: 'radio' }, + options: [ + 'large', + 'h1', + 'h2', + 'h3', + 'body1', + 'body2', + 'subtitle1', + 'subtitle2', + 'caption', + 'overline', + 'link1', + 'link2', + 'error', + ], }, - component: Typography, - tags: ['autodocs'], - title: 'Components/Typography', + }, + component: Typography, + tags: ['autodocs'], + title: 'Components/Typography', } satisfies Meta export default meta type Story = StoryObj export const Large: Story = { - args: { - children: 'Card content', - variant: 'large', - }, + args: { + children: 'Card content', + variant: 'large', + }, } export const H1: Story = { - args: { - children: 'Card content', - variant: 'h1', - }, + args: { + children: 'Card content', + variant: 'h1', + }, } export const H2: Story = { - args: { - children: 'Card content', - variant: 'h2', - }, + args: { + children: 'Card content', + variant: 'h2', + }, } export const H3: Story = { - args: { - children: 'Card content', - variant: 'h3', - }, + args: { + children: 'Card content', + variant: 'h3', + }, } export const Body1: Story = { - args: { - children: 'Card content', - variant: 'body1', - }, + args: { + children: 'Card content', + variant: 'body1', + }, } export const Body2: Story = { - args: { - children: 'Card content', - variant: 'body2', - }, + args: { + children: 'Card content', + variant: 'body2', + }, } export const Subtitle1: Story = { - args: { - children: 'Card content', - variant: 'subtitle1', - }, + args: { + children: 'Card content', + variant: 'subtitle1', + }, } export const Subtitle2: Story = { - args: { - children: 'Card content', - variant: 'subtitle2', - }, + args: { + children: 'Card content', + variant: 'subtitle2', + }, } export const Caption: Story = { - args: { - children: 'Card content', - variant: 'caption', - }, + args: { + children: 'Card content', + variant: 'caption', + }, } export const Overline: Story = { - args: { - children: 'Card content', - variant: 'overline', - }, + args: { + children: 'Card content', + variant: 'overline', + }, } export const Link1: Story = { - args: { - children: 'Card content', - variant: 'link1', - }, + args: { + children: 'Card content', + variant: 'link1', + }, } export const Link2: Story = { - args: { - children: 'Card content', - variant: 'link2', - }, + args: { + children: 'Card content', + variant: 'link2', + }, } export const Error: Story = { - args: { - children: 'Card content', - variant: 'error', - }, + args: { + children: 'Card content', + variant: 'error', + }, } diff --git a/src/components/ui/typography/typography.tsx b/src/components/ui/typography/typography.tsx index 18e66eb..472c2c1 100644 --- a/src/components/ui/typography/typography.tsx +++ b/src/components/ui/typography/typography.tsx @@ -5,33 +5,33 @@ import { clsx } from 'clsx' import s from './typography.module.scss' export interface TextProps { - as?: T - children?: ReactNode - className?: string - variant?: - | 'body1' - | 'body2' - | 'caption' - | 'error' - | 'h1' - | 'h2' - | 'h3' - | 'large' - | 'link1' - | 'link2' - | 'overline' - | 'subtitle1' - | 'subtitle2' + as?: T + children?: ReactNode + className?: string + variant?: + | 'body1' + | 'body2' + | 'caption' + | 'error' + | 'h1' + | 'h2' + | 'h3' + | 'large' + | 'link1' + | 'link2' + | 'overline' + | 'subtitle1' + | 'subtitle2' } export function Typography({ - as, - className, - variant = 'body1', - ...restProps + as, + className, + variant = 'body1', + ...restProps }: TextProps & Omit, keyof TextProps>) { - const classNames = clsx(s.text, s[variant], className) - const Component = as || 'p' + const classNames = clsx(s.text, s[variant], className) + const Component = as || 'p' - return + return } diff --git a/src/main.tsx b/src/main.tsx index cd75a3f..c4965f9 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -8,7 +8,7 @@ import '@fontsource/roboto/700.css' import './styles/index.scss' createRoot(document.getElementById('root')!).render( - - - + + + ) diff --git a/src/pages/deck-page/deck-page.tsx b/src/pages/deck-page/deck-page.tsx index c63a25a..54e8add 100644 --- a/src/pages/deck-page/deck-page.tsx +++ b/src/pages/deck-page/deck-page.tsx @@ -6,26 +6,26 @@ import { Pagination } from '@/components/ui/pagination' import { useGetDeckByIdQuery, useGetDeckCardsQuery } from '@/services' export const DeckPage = () => { - const { deckId } = useParams() - const [currentPage, setCurrentPage] = useState(1) - const { data: deckData } = useGetDeckByIdQuery({ id: deckId || '' }) - const { data: cardsData } = useGetDeckCardsQuery({ id: deckId || '' }) + const { deckId } = useParams() + const [currentPage, setCurrentPage] = useState(1) + const { data: deckData } = useGetDeckByIdQuery({ id: deckId || '' }) + const { data: cardsData } = useGetDeckCardsQuery({ id: deckId || '' }) - const learnLink = `/decks/${deckId}/learn` + const learnLink = `/decks/${deckId}/learn` - return ( - - {deckData?.name} - - Learn - - - - - - ) + return ( + + {deckData?.name} + + Learn + + + + + + ) } diff --git a/src/pages/decks-page/decks-page.tsx b/src/pages/decks-page/decks-page.tsx index 55e2c34..1da4d00 100644 --- a/src/pages/decks-page/decks-page.tsx +++ b/src/pages/decks-page/decks-page.tsx @@ -1,24 +1,23 @@ import { useState } from 'react' -import { Button, Page, Slider, TextField, Typography } from '@/components' -import { DecksTable } from '@/components' +import { Button, DecksTable, Page, Slider, TextField, Typography } from '@/components' import { DeckDialog } from '@/components/decks/deck-dialog' import { DeleteDeckDialog } from '@/components/decks/delete-deck-dialog' import { Pagination } from '@/components/ui/pagination' import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' import { - Tab, - useCreateDeckMutation, - useDeleteDeckMutation, - useGetDecksQuery, - useUpdateDeckMutation, + Tab, + useCreateDeckMutation, + useDeleteDeckMutation, + useGetDecksQuery, + useUpdateDeckMutation, } from '@/services/decks' import { - selectDecksCurrentPage, - selectDecksCurrentTab, - selectDecksMaxCards, - selectDecksMinCards, - selectDecksSearch, + selectDecksCurrentPage, + selectDecksCurrentTab, + selectDecksMaxCards, + selectDecksMinCards, + selectDecksSearch, } from '@/services/decks/decks.selectors' import { decksSlice } from '@/services/decks/decks.slice' import { useAppDispatch, useAppSelector } from '@/services/store' @@ -26,132 +25,127 @@ import { useAppDispatch, useAppSelector } from '@/services/store' import s from './decks-page.module.scss' export const DecksPage = () => { - const [showCreateModal, setShowCreateModal] = useState(false) - const [deckToDeleteId, setDeckToDeleteId] = useState(null) - const [deckToEditId, setDeckToEditId] = useState(null) + const [showCreateModal, setShowCreateModal] = useState(false) + const [deckToDeleteId, setDeckToDeleteId] = useState(null) + const [deckToEditId, setDeckToEditId] = useState(null) - const showEditModal = !!deckToEditId + const showEditModal = !!deckToEditId - const dispatch = useAppDispatch() - const currentPage = useAppSelector(selectDecksCurrentPage) - const minCards = useAppSelector(selectDecksMinCards) - const maxCards = useAppSelector(selectDecksMaxCards) - const currentTab = useAppSelector(selectDecksCurrentTab) - const search = useAppSelector(selectDecksSearch) - const setCurrentPage = (page: number) => dispatch(decksSlice.actions.setCurrentPage(page)) - const setMinCards = (minCards: number) => dispatch(decksSlice.actions.setMinCards(minCards)) - const setMaxCards = (maxCards: number) => dispatch(decksSlice.actions.setMaxCards(maxCards)) - const setSearch = (search: string) => dispatch(decksSlice.actions.setSearch(search)) - const setCurrentTab = (tab: Tab) => dispatch(decksSlice.actions.setCurrentTab(tab)) + const dispatch = useAppDispatch() + const currentPage = useAppSelector(selectDecksCurrentPage) + const minCards = useAppSelector(selectDecksMinCards) + const maxCards = useAppSelector(selectDecksMaxCards) + const currentTab = useAppSelector(selectDecksCurrentTab) + const search = useAppSelector(selectDecksSearch) + const setCurrentPage = (page: number) => dispatch(decksSlice.actions.setCurrentPage(page)) + const setMinCards = (minCards: number) => dispatch(decksSlice.actions.setMinCards(minCards)) + const setMaxCards = (maxCards: number) => dispatch(decksSlice.actions.setMaxCards(maxCards)) + const setSearch = (search: string) => dispatch(decksSlice.actions.setSearch(search)) + const setCurrentTab = (tab: Tab) => dispatch(decksSlice.actions.setCurrentTab(tab)) - const resetFilters = () => { - dispatch(decksSlice.actions.resetFilters()) - setRangeValue([0, decks?.maxCardsCount || undefined]) - } + const resetFilters = () => { + dispatch(decksSlice.actions.resetFilters()) + setRangeValue([0, decks?.maxCardsCount || undefined]) + } - const [rangeValue, setRangeValue] = useState([minCards, maxCards]) + const [rangeValue, setRangeValue] = useState([minCards, maxCards]) - const handleSliderCommitted = (value: number[]) => { - setMinCards(value[0]) - setMaxCards(value[1]) - } - const currentUserId = 'f2be95b9-4d07-4751-a775-bd612fc9553a' - const authorId = currentTab === 'my' ? currentUserId : undefined + const handleSliderCommitted = (value: number[]) => { + setMinCards(value[0]) + setMaxCards(value[1]) + } + const currentUserId = 'f2be95b9-4d07-4751-a775-bd612fc9553a' + const authorId = currentTab === 'my' ? currentUserId : undefined - const { data: decks } = useGetDecksQuery({ - authorId, - currentPage, - maxCardsCount: maxCards, - minCardsCount: minCards, - name: search, - }) + const { data: decks } = useGetDecksQuery({ + authorId, + currentPage, + maxCardsCount: maxCards, + minCardsCount: minCards, + name: search, + }) - const showConfirmDeleteModal = !!deckToDeleteId - const deckToDeleteName = decks?.items?.find(deck => deck.id === deckToDeleteId)?.name + const showConfirmDeleteModal = !!deckToDeleteId + const deckToDeleteName = decks?.items?.find(deck => deck.id === deckToDeleteId)?.name - const deckToEdit = decks?.items?.find(deck => deck.id === deckToEditId) + const deckToEdit = decks?.items?.find(deck => deck.id === deckToEditId) - const [createDeck] = useCreateDeckMutation() - const [deleteDeck] = useDeleteDeckMutation() - const [updateDeck] = useUpdateDeckMutation() - const openCreateModal = () => setShowCreateModal(true) + const [createDeck] = useCreateDeckMutation() + const [deleteDeck] = useDeleteDeckMutation() + const [updateDeck] = useUpdateDeckMutation() + const openCreateModal = () => setShowCreateModal(true) - if (!decks) { - return loading... - } + if (!decks) { + return loading... + } - return ( - - setDeckToDeleteId(null)} - onConfirm={() => { - deleteDeck({ id: deckToDeleteId ?? '' }) - setDeckToDeleteId(null) - }} - onOpenChange={() => setDeckToDeleteId(null)} - open={showConfirmDeleteModal} - /> - { - if (!deckToEditId) { - return - } + return ( + + setDeckToDeleteId(null)} + onConfirm={() => { + deleteDeck({ id: deckToDeleteId ?? '' }) + setDeckToDeleteId(null) + }} + onOpenChange={() => setDeckToDeleteId(null)} + open={showConfirmDeleteModal} + /> + { + if (!deckToEditId) { + return + } - updateDeck({ id: deckToEditId, ...data }) - }} - onOpenChange={() => setDeckToEditId(null)} - open={showEditModal} - /> - - - Decks - Add new deck - setShowCreateModal(false)} - onConfirm={createDeck} - onOpenChange={setShowCreateModal} - open={showCreateModal} - /> - - - - setCurrentTab(value as Tab)} value={currentTab}> - - My decks - All decks - - - - - Clear filters - - - - - - - ) + updateDeck({ id: deckToEditId, ...data }) + }} + onOpenChange={() => setDeckToEditId(null)} + open={showEditModal} + /> + + + Decks + Add new deck + setShowCreateModal(false)} + onConfirm={createDeck} + onOpenChange={setShowCreateModal} + open={showCreateModal} + /> + + + + setCurrentTab(value as Tab)} value={currentTab}> + + My decks + All decks + + + + + Clear filters + + + + + + + ) } diff --git a/src/pages/sign-in-page/sign-in-page.tsx b/src/pages/sign-in-page/sign-in-page.tsx index 0c46bd7..9124647 100644 --- a/src/pages/sign-in-page/sign-in-page.tsx +++ b/src/pages/sign-in-page/sign-in-page.tsx @@ -1,9 +1,9 @@ import { Page, SignIn } from '@/components' export const SignInPage = () => { - return ( - - {}} /> - - ) + return ( + + {}} /> + + ) } diff --git a/src/router.tsx b/src/router.tsx index 83dbe18..c46122e 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -1,51 +1,51 @@ import { - Navigate, - Outlet, - RouteObject, - RouterProvider, - createBrowserRouter, + Navigate, + Outlet, + RouteObject, + RouterProvider, + createBrowserRouter, } from 'react-router-dom' import { DecksPage, SignInPage } from './pages' import { DeckPage } from '@/pages/deck-page/deck-page' const publicRoutes: RouteObject[] = [ - { - children: [ - { - element: , - path: '/login', - }, - ], - element: , - }, + { + children: [ + { + element: , + path: '/login', + }, + ], + element: , + }, ] const privateRoutes: RouteObject[] = [ - { - element: , - path: '/', - }, - { - element: , - path: '/decks/:deckId', - }, + { + element: , + path: '/', + }, + { + element: , + path: '/decks/:deckId', + }, ] const router = createBrowserRouter([ - { - children: privateRoutes, - element: , - }, - ...publicRoutes, + { + children: privateRoutes, + element: , + }, + ...publicRoutes, ]) export const Router = () => { - return + return } function PrivateRoutes() { - const isAuthenticated = true + const isAuthenticated = true - return isAuthenticated ? : + return isAuthenticated ? : } diff --git a/src/services/base-api.ts b/src/services/base-api.ts index 1d39e43..f2f9776 100644 --- a/src/services/base-api.ts +++ b/src/services/base-api.ts @@ -1,14 +1,14 @@ import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react' export const baseApi = createApi({ - baseQuery: fetchBaseQuery({ - baseUrl: 'https://api.flashcards.andrii.es', - credentials: 'include', - prepareHeaders: headers => { - headers.append('x-auth-skip', 'true') - }, - }), - endpoints: () => ({}), - reducerPath: 'baseApi', - tagTypes: ['Decks'], + baseQuery: fetchBaseQuery({ + baseUrl: 'https://api.flashcards.andrii.es', + credentials: 'include', + prepareHeaders: headers => { + headers.append('x-auth-skip', 'true') + }, + }), + endpoints: () => ({}), + reducerPath: 'baseApi', + tagTypes: ['Decks'], }) diff --git a/src/services/decks/decks.service.ts b/src/services/decks/decks.service.ts index 3e24d22..cc8baa8 100644 --- a/src/services/decks/decks.service.ts +++ b/src/services/decks/decks.service.ts @@ -1,68 +1,68 @@ import { - CardsResponse, - CreateDeckArgs, - DeckResponse, - DecksResponse, - GetDecksArgs, - UpdateDeckArgs, + CardsResponse, + CreateDeckArgs, + DeckResponse, + DecksResponse, + GetDecksArgs, + UpdateDeckArgs, } from './decks.types' import { baseApi } from '@/services' const decksService = baseApi.injectEndpoints({ - endpoints: builder => ({ - createDeck: builder.mutation({ - invalidatesTags: ['Decks'], - onQueryStarted: async (_, { dispatch, getCacheEntry, getState, queryFulfilled }) => { - const data = getCacheEntry() - const state = getState() + endpoints: builder => ({ + createDeck: builder.mutation({ + invalidatesTags: ['Decks'], + onQueryStarted: async (_, { dispatch, getCacheEntry, getState, queryFulfilled }) => { + const data = getCacheEntry() + const state = getState() - decksService.util.re - await queryFulfilled - }, - query: body => ({ - body, - method: 'POST', - url: `v1/decks`, - }), - }), - deleteDeck: builder.mutation({ - invalidatesTags: ['Decks'], - query: ({ id }) => ({ - method: 'DELETE', - url: `v1/decks/${id}`, - }), - }), - getDeckById: builder.query({ - query: ({ id }) => `v1/decks/${id}`, - }), - getDeckCards: builder.query({ - query: ({ id }) => `v1/decks/${id}/cards`, - }), - getDecks: builder.query({ - providesTags: ['Decks'], - query: args => { - return { - params: args ?? undefined, - url: `v1/decks`, - } - }, - }), - updateDeck: builder.mutation({ - invalidatesTags: ['Decks'], - query: ({ id, ...body }) => ({ - body, - method: 'PATCH', - url: `v1/decks/${id}`, - }), - }), + decksService.util.re + await queryFulfilled + }, + query: body => ({ + body, + method: 'POST', + url: `v1/decks`, + }), }), + deleteDeck: builder.mutation({ + invalidatesTags: ['Decks'], + query: ({ id }) => ({ + method: 'DELETE', + url: `v1/decks/${id}`, + }), + }), + getDeckById: builder.query({ + query: ({ id }) => `v1/decks/${id}`, + }), + getDeckCards: builder.query({ + query: ({ id }) => `v1/decks/${id}/cards`, + }), + getDecks: builder.query({ + providesTags: ['Decks'], + query: args => { + return { + params: args ?? undefined, + url: `v1/decks`, + } + }, + }), + updateDeck: builder.mutation({ + invalidatesTags: ['Decks'], + query: ({ id, ...body }) => ({ + body, + method: 'PATCH', + url: `v1/decks/${id}`, + }), + }), + }), }) export const { - useCreateDeckMutation, - useDeleteDeckMutation, - useGetDeckByIdQuery, - useGetDeckCardsQuery, - useGetDecksQuery, - useUpdateDeckMutation, + useCreateDeckMutation, + useDeleteDeckMutation, + useGetDeckByIdQuery, + useGetDeckCardsQuery, + useGetDecksQuery, + useUpdateDeckMutation, } = decksService diff --git a/src/services/decks/decks.slice.ts b/src/services/decks/decks.slice.ts index 58ea12f..0d1f8fb 100644 --- a/src/services/decks/decks.slice.ts +++ b/src/services/decks/decks.slice.ts @@ -2,42 +2,42 @@ import { Tab } from '@/services' import { PayloadAction, createSlice } from '@reduxjs/toolkit' export const decksSlice = createSlice({ - initialState: { - currentPage: 1, - currentTab: 'all' as Tab, - maxCards: undefined as number | undefined, - minCards: 0, - perPage: 10, - search: '', + initialState: { + currentPage: 1, + currentTab: 'all' as Tab, + maxCards: undefined as number | undefined, + minCards: 0, + perPage: 10, + search: '', + }, + name: 'decks', + reducers: { + resetCurrentPage: state => { + state.currentPage = 1 }, - name: 'decks', - reducers: { - resetCurrentPage: state => { - state.currentPage = 1 - }, - resetFilters: state => { - state.search = '' - state.currentTab = 'all' - state.minCards = 0 - state.maxCards = undefined - }, - setCurrentPage: (state, action: PayloadAction) => { - state.currentPage = action.payload - }, - setCurrentTab: (state, action: PayloadAction) => { - state.currentTab = action.payload - }, - setMaxCards: (state, action: PayloadAction) => { - state.maxCards = action.payload - }, - setMinCards: (state, action: PayloadAction) => { - state.minCards = action.payload - }, - setPerPage: (state, action: PayloadAction) => { - state.perPage = action.payload - }, - setSearch: (state, action: PayloadAction) => { - state.search = action.payload - }, + resetFilters: state => { + state.search = '' + state.currentTab = 'all' + state.minCards = 0 + state.maxCards = undefined }, + setCurrentPage: (state, action: PayloadAction) => { + state.currentPage = action.payload + }, + setCurrentTab: (state, action: PayloadAction) => { + state.currentTab = action.payload + }, + setMaxCards: (state, action: PayloadAction) => { + state.maxCards = action.payload + }, + setMinCards: (state, action: PayloadAction) => { + state.minCards = action.payload + }, + setPerPage: (state, action: PayloadAction) => { + state.perPage = action.payload + }, + setSearch: (state, action: PayloadAction) => { + state.search = action.payload + }, + }, }) diff --git a/src/services/decks/decks.types.ts b/src/services/decks/decks.types.ts index 0a452e7..b8c005c 100644 --- a/src/services/decks/decks.types.ts +++ b/src/services/decks/decks.types.ts @@ -1,72 +1,72 @@ export type Pagination = { - currentPage: number - itemsPerPage: number - totalItems: number - totalPages: number + currentPage: number + itemsPerPage: number + totalItems: number + totalPages: number } export type Author = { - id: string - name: string + id: string + name: string } export type Deck = { - author: Author - cardsCount: number - cover?: null | string - created: string - id: string - isBlocked?: boolean | null - isDeleted: boolean | null - isPrivate: boolean - name: string - rating: number - shots: number - updated: string - userId: string + author: Author + cardsCount: number + cover?: null | string + created: string + id: string + isBlocked?: boolean | null + isDeleted: boolean | null + isPrivate: boolean + name: string + rating: number + shots: number + updated: string + userId: string } export type DecksResponse = { - items: Deck[] - maxCardsCount: number - pagination: Pagination + items: Deck[] + maxCardsCount: number + pagination: Pagination } export type DeckResponse = Deck export type CardsResponse = { - items: Card[] - pagination: Pagination + items: Card[] + pagination: Pagination } export type Card = { - answer: string - answerImg?: null | string - created: string - deckId: string - grade: number - id: string - question: string - questionImg?: null | string - shots: number - updated: string - userId: string + answer: string + answerImg?: null | string + created: string + deckId: string + grade: number + id: string + question: string + questionImg?: null | string + shots: number + updated: string + userId: string } export type GetDecksArgs = { - authorId?: string - currentPage?: number - itemsPerPage?: number - maxCardsCount?: number - minCardsCount?: number - name?: string - orderBy?: string + authorId?: string + currentPage?: number + itemsPerPage?: number + maxCardsCount?: number + minCardsCount?: number + name?: string + orderBy?: string } export type CreateDeckArgs = { - cover?: string - isPrivate?: boolean - name: string + cover?: string + isPrivate?: boolean + name: string } export type UpdateDeckArgs = Partial & { id: Deck['id'] } diff --git a/src/services/store.ts b/src/services/store.ts index 5e20ee1..29a6c32 100644 --- a/src/services/store.ts +++ b/src/services/store.ts @@ -6,11 +6,11 @@ import { configureStore } from '@reduxjs/toolkit' import { setupListeners } from '@reduxjs/toolkit/query/react' export const store = configureStore({ - middleware: getDefaultMiddleware => getDefaultMiddleware().concat(baseApi.middleware), - reducer: { - [baseApi.reducerPath]: baseApi.reducer, - [decksSlice.name]: decksSlice.reducer, - }, + middleware: getDefaultMiddleware => getDefaultMiddleware().concat(baseApi.middleware), + reducer: { + [baseApi.reducerPath]: baseApi.reducer, + [decksSlice.name]: decksSlice.reducer, + }, }) export type AppDispatch = typeof store.dispatch diff --git a/src/utils/date/format-date.ts b/src/utils/date/format-date.ts index dff64bf..4575f30 100644 --- a/src/utils/date/format-date.ts +++ b/src/utils/date/format-date.ts @@ -1,7 +1,7 @@ export function formatDate(date: string | undefined) { - if (!date) { - return '' - } + if (!date) { + return '' + } - return new Date(date).toLocaleDateString('ru-RU') + return new Date(date).toLocaleDateString('ru-RU') } diff --git a/vite.config.ts b/vite.config.ts index ab930de..329cfa9 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,8 +5,8 @@ import { defineConfig } from 'vite' // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], - resolve: { - alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], - }, + plugins: [react()], + resolve: { + alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }], + }, })
- Do you really want to remove {deckName}? -
All cards will be deleted.
+ Do you really want to remove {deckName}? +