From 450d664f3414a785c1e5253ab39d068b24534a07 Mon Sep 17 00:00:00 2001 From: andres Date: Sat, 9 Sep 2023 17:03:16 +0200 Subject: [PATCH] add components --- package.json | 6 +- pnpm-lock.yaml | 66 +++++++++++++- src/assets/icons/index.ts | 1 + src/assets/icons/search.tsx | 26 ++++++ src/components/decks/decks-table.tsx | 0 .../ui/checkbox/checkbox.module.scss | 1 - src/components/ui/index.ts | 3 + src/components/ui/page/index.ts | 1 + src/components/ui/page/page.module.scss | 6 ++ src/components/ui/page/page.tsx | 15 ++++ src/components/ui/slider/index.ts | 1 + src/components/ui/slider/slider.module.scss | 52 +++++++++++ src/components/ui/slider/slider.tsx | 26 ++++++ .../ui/table/{index.tsx => index.ts} | 0 src/components/ui/table/table.module.scss | 1 + src/components/ui/table/table.tsx | 46 ++++++++++ src/components/ui/tabs/index.ts | 1 + src/components/ui/tabs/tabs.module.scss | 34 ++++++++ src/components/ui/tabs/tabs.tsx | 37 ++++++++ .../ui/text-field/text-field.module.scss | 25 ++++++ src/components/ui/text-field/text-field.tsx | 8 +- src/main.tsx | 2 +- src/pages/decks-page/decks-page.module.scss | 17 ++++ src/pages/decks-page/decks-page.tsx | 87 +++++++++++++++++++ src/pages/decks-page/index.ts | 1 + src/pages/index.ts | 2 + src/pages/sign-in-page/index.ts | 1 + src/pages/sign-in-page/sign-in-page.tsx | 9 ++ src/router.tsx | 21 +++-- src/services/base-api.ts | 10 +-- src/services/decks/decks.service.ts | 13 +++ src/services/decks/decks.types.ts | 33 +++++++ src/services/decks/index.ts | 2 + src/services/index.ts | 1 + src/styles/_boilerplate.scss | 20 +++++ 35 files changed, 550 insertions(+), 25 deletions(-) create mode 100644 src/assets/icons/search.tsx create mode 100644 src/components/decks/decks-table.tsx create mode 100644 src/components/ui/page/index.ts create mode 100644 src/components/ui/page/page.module.scss create mode 100644 src/components/ui/page/page.tsx create mode 100644 src/components/ui/slider/index.ts create mode 100644 src/components/ui/slider/slider.module.scss create mode 100644 src/components/ui/slider/slider.tsx rename src/components/ui/table/{index.tsx => index.ts} (100%) create mode 100644 src/components/ui/tabs/index.ts create mode 100644 src/components/ui/tabs/tabs.module.scss create mode 100644 src/components/ui/tabs/tabs.tsx create mode 100644 src/pages/decks-page/decks-page.module.scss create mode 100644 src/pages/decks-page/decks-page.tsx create mode 100644 src/pages/decks-page/index.ts create mode 100644 src/pages/index.ts create mode 100644 src/pages/sign-in-page/index.ts create mode 100644 src/pages/sign-in-page/sign-in-page.tsx create mode 100644 src/services/decks/decks.service.ts create mode 100644 src/services/decks/decks.types.ts create mode 100644 src/services/decks/index.ts create mode 100644 src/services/index.ts diff --git a/package.json b/package.json index 6a4f64f..8fc62e6 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,8 @@ "@radix-ui/react-checkbox": "^1.0.4", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-radio-group": "^1.1.3", + "@radix-ui/react-slider": "^1.1.2", + "@radix-ui/react-tabs": "^1.0.4", "@reduxjs/toolkit": "^1.9.5", "@storybook/theming": "^7.2.1", "clsx": "^2.0.0", @@ -51,6 +53,7 @@ "@typescript-eslint/parser": "^6.0.0", "@vitejs/plugin-react": "^4.0.3", "eslint": "^8.45.0", + "eslint-plugin-myPlugin": "file:./eslint", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "eslint-plugin-storybook": "^0.6.13", @@ -58,7 +61,6 @@ "storybook": "^7.2.1", "stylelint": "^15.10.2", "typescript": "^5.0.2", - "vite": "^4.4.5", - "eslint-plugin-myPlugin": "file:./eslint" + "vite": "^4.4.5" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ccdb962..6cec91c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,12 @@ dependencies: '@radix-ui/react-radio-group': specifier: ^1.1.3 version: 1.1.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-slider': + specifier: ^1.1.2 + version: 1.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-tabs': + specifier: ^1.0.4 + version: 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) '@reduxjs/toolkit': specifier: ^1.9.5 version: 1.9.5(react-redux@8.1.2)(react@18.2.0) @@ -2547,6 +2553,37 @@ packages: react-dom: 18.2.0(react@18.2.0) react-remove-scroll: 2.5.5(@types/react@18.2.15)(react@18.2.0) + /@radix-ui/react-slider@1.1.2(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-NKs15MJylfzVsCagVSWKhGGLNR1W9qWs+HtgbmjjVUB3B9+lb3PYoXxVju3kOrpf0VKyVCtZp+iTwVoqpa1Chw==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.6 + '@radix-ui/number': 1.0.1 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-context': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-use-previous': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-use-size': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@types/react': 18.2.15 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-slot@1.0.2(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==} peerDependencies: @@ -2561,6 +2598,34 @@ packages: '@types/react': 18.2.15 react: 18.2.0 + /@radix-ui/react-tabs@1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 + react-dom: ^16.8 || ^17.0 || ^18.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + dependencies: + '@babel/runtime': 7.22.6 + '@radix-ui/primitive': 1.0.1 + '@radix-ui/react-context': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-direction': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-id': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-roving-focus': 1.0.4(@types/react-dom@18.2.7)(@types/react@18.2.15)(react-dom@18.2.0)(react@18.2.0) + '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.15)(react@18.2.0) + '@types/react': 18.2.15 + '@types/react-dom': 18.2.7 + react: 18.2.0 + react-dom: 18.2.0(react@18.2.0) + dev: false + /@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.15)(react@18.2.0): resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==} peerDependencies: @@ -10217,5 +10282,4 @@ packages: file:eslint: resolution: {directory: eslint, type: directory} name: eslint - version: 0.0.0 dev: true diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index adf3ef0..1753e98 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -9,3 +9,4 @@ export { default as Logo } from './logo' export { default as PersonOutline } from './person-outline' export { default as ChevronUp } from './chevron-up' export { default as Close } from './close' +export { default as Search } from './search' diff --git a/src/assets/icons/search.tsx b/src/assets/icons/search.tsx new file mode 100644 index 0000000..5a2b6f0 --- /dev/null +++ b/src/assets/icons/search.tsx @@ -0,0 +1,26 @@ +import { SVGProps, Ref, forwardRef, memo } from 'react' +const SvgComponent = (props: SVGProps, ref: Ref) => ( + + + + + + + + + + +) + +export default memo(forwardRef(SvgComponent)) diff --git a/src/components/decks/decks-table.tsx b/src/components/decks/decks-table.tsx new file mode 100644 index 0000000..e69de29 diff --git a/src/components/ui/checkbox/checkbox.module.scss b/src/components/ui/checkbox/checkbox.module.scss index 2a82b44..d262ecf 100644 --- a/src/components/ui/checkbox/checkbox.module.scss +++ b/src/components/ui/checkbox/checkbox.module.scss @@ -52,7 +52,6 @@ width: 36px; height: 36px; - background-color: var(--color-dark-900); border-radius: 50%; &.disabled { diff --git a/src/components/ui/index.ts b/src/components/ui/index.ts index 15a494d..d5a1afb 100644 --- a/src/components/ui/index.ts +++ b/src/components/ui/index.ts @@ -3,5 +3,8 @@ export * from './card' export * from './typography' export * from './checkbox' export * from './text-field' +export * from './table' export * from './controlled' export * from './radio-group' +export * from './page' +export * from './slider' diff --git a/src/components/ui/page/index.ts b/src/components/ui/page/index.ts new file mode 100644 index 0000000..feed53c --- /dev/null +++ b/src/components/ui/page/index.ts @@ -0,0 +1 @@ +export * from './page' diff --git a/src/components/ui/page/page.module.scss b/src/components/ui/page/page.module.scss new file mode 100644 index 0000000..077066d --- /dev/null +++ b/src/components/ui/page/page.module.scss @@ -0,0 +1,6 @@ +.root { + display: flex; + justify-content: center; + margin-top: 36px; + padding-inline: 24px; +} diff --git a/src/components/ui/page/page.tsx b/src/components/ui/page/page.tsx new file mode 100644 index 0000000..ea0bcc1 --- /dev/null +++ b/src/components/ui/page/page.tsx @@ -0,0 +1,15 @@ +import { ComponentPropsWithoutRef, forwardRef } from 'react' + +import { clsx } from 'clsx' + +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), + } + + return
+}) diff --git a/src/components/ui/slider/index.ts b/src/components/ui/slider/index.ts new file mode 100644 index 0000000..6d0e339 --- /dev/null +++ b/src/components/ui/slider/index.ts @@ -0,0 +1 @@ +export * from './slider' diff --git a/src/components/ui/slider/slider.module.scss b/src/components/ui/slider/slider.module.scss new file mode 100644 index 0000000..e00a847 --- /dev/null +++ b/src/components/ui/slider/slider.module.scss @@ -0,0 +1,52 @@ +.container { + display: flex; + gap: 10px; + align-items: center; + justify-content: center; + + width: 100%; +} + +.root { + touch-action: none; + user-select: none; + + position: relative; + + display: flex; + align-items: center; + + width: 100%; +} + +.track { + position: relative; + + width: 100%; + height: 4px; + + opacity: 0.5; + background-color: var(--color-accent-500); + border-radius: 2px; +} + +.range { + position: absolute; + height: 100%; + background-color: var(--color-accent-500); +} + +.thumb { + touch-action: pan-x; + cursor: pointer; + + display: block; + + width: 16px; + height: 16px; + + background-color: var(--color-light-100); + border-radius: 9999px; + + transition: transform 0.2s ease-in-out; +} diff --git a/src/components/ui/slider/slider.tsx b/src/components/ui/slider/slider.tsx new file mode 100644 index 0000000..e19137f --- /dev/null +++ b/src/components/ui/slider/slider.tsx @@ -0,0 +1,26 @@ +import { ComponentPropsWithoutRef, ElementRef, forwardRef } from 'react' + +import * as SliderPrimitive from '@radix-ui/react-slider' +import { clsx } from 'clsx' + +import s from './slider.module.scss' +const Slider = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( +
+ {props?.value?.[0]} + + + + + + + + {props?.value?.[1]} +
+)) + +Slider.displayName = SliderPrimitive.Root.displayName + +export { Slider } diff --git a/src/components/ui/table/index.tsx b/src/components/ui/table/index.ts similarity index 100% rename from src/components/ui/table/index.tsx rename to src/components/ui/table/index.ts diff --git a/src/components/ui/table/table.module.scss b/src/components/ui/table/table.module.scss index 2a0b4fe..0709736 100644 --- a/src/components/ui/table/table.module.scss +++ b/src/components/ui/table/table.module.scss @@ -1,5 +1,6 @@ .table { border-collapse: collapse; + width: 100%; color: var(--color-light-100); border: 1px solid var(--color-dark-500); } diff --git a/src/components/ui/table/table.tsx b/src/components/ui/table/table.tsx index 603012b..869ec7b 100644 --- a/src/components/ui/table/table.tsx +++ b/src/components/ui/table/table.tsx @@ -75,3 +75,49 @@ export const TableEmpty: FC & { mt?: string; mb?: string } ) } +export type Column = { + key: string + title: string + sortable?: boolean +} +export type Sort = { + key: string + direction: 'asc' | 'desc' +} | null + +export const TableHeader: FC< + Omit< + ComponentPropsWithoutRef<'thead'> & { + columns: Column[] + sort?: Sort + onSort?: (sort: Sort) => void + }, + 'children' + > +> = ({ columns, sort, onSort, ...restProps }) => { + const handleSort = (key: string, sortable?: boolean) => () => { + if (!onSort || !sortable) return + + if (sort?.key !== key) return onSort({ key, direction: 'asc' }) + + if (sort.direction === 'desc') return onSort(null) + + return onSort({ + key, + direction: sort?.direction === 'asc' ? 'desc' : 'asc', + }) + } + + return ( + + + {columns.map(({ title, key, sortable = true }) => ( + + {title} + {sort && sort.key === key && {sort.direction === 'asc' ? '▲' : '▼'}} + + ))} + + + ) +} diff --git a/src/components/ui/tabs/index.ts b/src/components/ui/tabs/index.ts new file mode 100644 index 0000000..3fb765f --- /dev/null +++ b/src/components/ui/tabs/index.ts @@ -0,0 +1 @@ +export * from './tabs' diff --git a/src/components/ui/tabs/tabs.module.scss b/src/components/ui/tabs/tabs.module.scss new file mode 100644 index 0000000..554bf40 --- /dev/null +++ b/src/components/ui/tabs/tabs.module.scss @@ -0,0 +1,34 @@ +.list { + display: inline-flex; + background-color: var(--color-dark-900); +} + +.trigger { + cursor: pointer; + + display: inline-flex; + flex-shrink: 0; + flex-wrap: nowrap; + + padding: 6px 24px; + + background-color: var(--color-dark-900); + border: 1px solid var(--color-dark-300); + + &:last-of-type { + border-radius: 0 2px 2px 0; + } + + &:first-of-type { + border-radius: 2px 0 0 2px; + } + + &[data-state='active'] { + background-color: var(--color-accent-500); + border-color: var(--color-accent-500); + } +} + +.content { + color: inherit; +} diff --git a/src/components/ui/tabs/tabs.tsx b/src/components/ui/tabs/tabs.tsx new file mode 100644 index 0000000..9829cd2 --- /dev/null +++ b/src/components/ui/tabs/tabs.tsx @@ -0,0 +1,37 @@ +import { ComponentPropsWithoutRef, ElementRef, forwardRef } from 'react' + +import * as TabsPrimitive from '@radix-ui/react-tabs' +import { clsx } from 'clsx' + +import s from './tabs.module.scss' + +const Tabs = TabsPrimitive.Root + +const TabsList = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +TabsList.displayName = TabsPrimitive.List.displayName + +const TabsTrigger = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +TabsTrigger.displayName = TabsPrimitive.Trigger.displayName + +const TabsContent = forwardRef< + ElementRef, + ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) + +TabsContent.displayName = TabsPrimitive.Content.displayName + +export { Tabs, TabsList, TabsTrigger, TabsContent } diff --git a/src/components/ui/text-field/text-field.module.scss b/src/components/ui/text-field/text-field.module.scss index ae34ae8..eaeb347 100644 --- a/src/components/ui/text-field/text-field.module.scss +++ b/src/components/ui/text-field/text-field.module.scss @@ -40,6 +40,10 @@ color: var(--color-danger-300); border-color: var(--color-danger-300); } + + &.hasLeadingIcon { + padding-left: 41px; + } } .label { @@ -47,6 +51,27 @@ color: var(--color-dark-100); } +.leadingIcon { + position: absolute; + top: 50%; + bottom: 50%; + left: 0; + transform: translateY(-50%); + + width: 20px; + height: 20px; + margin-left: 12px; + padding: 0; + + background: transparent; + border: 0; + outline: 0; + + &:focus-visible { + outline: var(--outline-focus); + } +} + .showPassword { cursor: pointer; diff --git a/src/components/ui/text-field/text-field.tsx b/src/components/ui/text-field/text-field.tsx index 2ce052e..fcac9b8 100644 --- a/src/components/ui/text-field/text-field.tsx +++ b/src/components/ui/text-field/text-field.tsx @@ -4,7 +4,7 @@ import { clsx } from 'clsx' import s from './text-field.module.scss' -import { VisibilityOff, Eye } from '@/assets' +import { VisibilityOff, Eye, Search } from '@/assets' import { Typography } from '@/components' export type TextFieldProps = { @@ -13,6 +13,7 @@ export type TextFieldProps = { labelProps?: ComponentProps<'label'> errorMessage?: string label?: string + search?: boolean } & ComponentPropsWithoutRef<'input'> export const TextField = forwardRef( @@ -27,6 +28,7 @@ export const TextField = forwardRef( label, onChange, onValueChange, + search, ...restProps }, ref @@ -45,9 +47,10 @@ export const TextField = forwardRef( const classNames = { root: clsx(s.root, containerProps?.className), fieldContainer: clsx(s.fieldContainer), - field: clsx(s.field, !!errorMessage && s.error, className), + field: clsx(s.field, !!errorMessage && s.error, search && s.hasLeadingIcon, className), label: clsx(s.label, labelProps?.className), error: clsx(s.error), + leadingIcon: s.leadingIcon, } return ( @@ -58,6 +61,7 @@ export const TextField = forwardRef( )}
+ {search && } diff --git a/src/pages/decks-page/decks-page.module.scss b/src/pages/decks-page/decks-page.module.scss new file mode 100644 index 0000000..ca89803 --- /dev/null +++ b/src/pages/decks-page/decks-page.module.scss @@ -0,0 +1,17 @@ +.root { + width: 100%; +} + +.header { + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; +} + +.filters { + display: flex; + grid-template-columns: repeat(4, 1fr); + column-gap: 16px; + margin-bottom: 16px; +} diff --git a/src/pages/decks-page/decks-page.tsx b/src/pages/decks-page/decks-page.tsx new file mode 100644 index 0000000..2191d7c --- /dev/null +++ b/src/pages/decks-page/decks-page.tsx @@ -0,0 +1,87 @@ +import { useState } from 'react' + +import s from './decks-page.module.scss' + +import { + Button, + Page, + Typography, + Column, + Table, + TableBody, + TableCell, + TableHeader, + TableRow, + TextField, + Slider, +} from '@/components' +import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs' +import { useGetDecksQuery } from '@/services/decks' + +const columns: Column[] = [ + { + key: 'name', + title: 'Name', + }, + { + key: 'cardsCount', + title: 'Cards', + }, + { + key: 'updated', + title: 'Last Updated', + }, + { + key: 'author', + title: 'Created By', + }, + { + key: 'actions', + title: '', + }, +] + +export const DecksPage = () => { + const { data: decks } = useGetDecksQuery() + const [activeTab, setActiveTab] = useState('my') + const [range, setRange] = useState([0, 100]) + const [rangeValue, setRangeValue] = useState([0, 1]) + + if (!decks) return
loading...
+ + return ( + +
+
+ Decks + +
+
+ + + + My decks + All decks + + + + +
+ + + + {decks?.items.map(deck => ( + + {deck.name} + {deck.cardsCount} + {deck.updated} + {deck.author.name} + ... + + ))} + +
+
+
+ ) +} diff --git a/src/pages/decks-page/index.ts b/src/pages/decks-page/index.ts new file mode 100644 index 0000000..be7e2f1 --- /dev/null +++ b/src/pages/decks-page/index.ts @@ -0,0 +1 @@ +export * from './decks-page' diff --git a/src/pages/index.ts b/src/pages/index.ts new file mode 100644 index 0000000..aaa0cf8 --- /dev/null +++ b/src/pages/index.ts @@ -0,0 +1,2 @@ +export * from './sign-in-page' +export * from './decks-page' diff --git a/src/pages/sign-in-page/index.ts b/src/pages/sign-in-page/index.ts new file mode 100644 index 0000000..0810160 --- /dev/null +++ b/src/pages/sign-in-page/index.ts @@ -0,0 +1 @@ +export * from './sign-in-page' diff --git a/src/pages/sign-in-page/sign-in-page.tsx b/src/pages/sign-in-page/sign-in-page.tsx new file mode 100644 index 0000000..6d1e8ce --- /dev/null +++ b/src/pages/sign-in-page/sign-in-page.tsx @@ -0,0 +1,9 @@ +import { SignIn, Page } from '@/components' + +export const SignInPage = () => { + return ( + + {}} /> + + ) +} diff --git a/src/router.tsx b/src/router.tsx index 939fe1d..e6feaa0 100644 --- a/src/router.tsx +++ b/src/router.tsx @@ -6,21 +6,27 @@ import { RouterProvider, } from 'react-router-dom' -import { useGetDecksQuery } from '@/services/base-api' +import { SignInPage, DecksPage } from './pages' const publicRoutes: RouteObject[] = [ { - path: '/login', - element:
login
, + element: , + children: [ + { + path: '/login', + element: , + }, + ], }, ] const privateRoutes: RouteObject[] = [ { path: '/', - element:
hello
, + element: , }, ] + const router = createBrowserRouter([ { element: , @@ -30,14 +36,11 @@ const router = createBrowserRouter([ ]) export const Router = () => { - const result = useGetDecksQuery() - - console.log(result) - return } + function PrivateRoutes() { - const isAuthenticated = false + const isAuthenticated = true return isAuthenticated ? : } diff --git a/src/services/base-api.ts b/src/services/base-api.ts index 9f21d8a..101bf44 100644 --- a/src/services/base-api.ts +++ b/src/services/base-api.ts @@ -9,13 +9,5 @@ export const baseApi = createApi({ headers.append('x-auth-skip', 'true') }, }), - endpoints: builder => { - return { - getDecks: builder.query({ - query: () => `v1/decks`, - }), - } - }, + endpoints: () => ({}), }) - -export const { useGetDecksQuery } = baseApi diff --git a/src/services/decks/decks.service.ts b/src/services/decks/decks.service.ts new file mode 100644 index 0000000..fb995e1 --- /dev/null +++ b/src/services/decks/decks.service.ts @@ -0,0 +1,13 @@ +import { DecksResponse } from './decks.types' + +import { baseApi } from '@/services' + +const decksService = baseApi.injectEndpoints({ + endpoints: builder => ({ + getDecks: builder.query({ + query: () => `v1/decks`, + }), + }), +}) + +export const { useGetDecksQuery } = decksService diff --git a/src/services/decks/decks.types.ts b/src/services/decks/decks.types.ts new file mode 100644 index 0000000..742918f --- /dev/null +++ b/src/services/decks/decks.types.ts @@ -0,0 +1,33 @@ +export type Pagination = { + totalPages: number + currentPage: number + itemsPerPage: number + totalItems: number +} + +export type Author = { + id: string + name: string +} + +export type Deck = { + id: string + userId: string + name: string + isPrivate: boolean + shots: number + cover?: string | null + rating: number + isDeleted: boolean | null + isBlocked?: boolean | null + created: string + updated: string + cardsCount: number + author: Author +} + +export type DecksResponse = { + maxCardsCount: number + pagination: Pagination + items: Deck[] +} diff --git a/src/services/decks/index.ts b/src/services/decks/index.ts new file mode 100644 index 0000000..0aefe7b --- /dev/null +++ b/src/services/decks/index.ts @@ -0,0 +1,2 @@ +export * from './decks.service' +export * from './decks.types' diff --git a/src/services/index.ts b/src/services/index.ts new file mode 100644 index 0000000..02efb7a --- /dev/null +++ b/src/services/index.ts @@ -0,0 +1 @@ +export * from './base-api' diff --git a/src/styles/_boilerplate.scss b/src/styles/_boilerplate.scss index 7608177..63d4884 100644 --- a/src/styles/_boilerplate.scss +++ b/src/styles/_boilerplate.scss @@ -39,3 +39,23 @@ body { background-color: var(--color-dark-900); } + +input:-webkit-autofill, +input:-webkit-autofill:hover, +input:-webkit-autofill:focus input:-webkit-autofill, +textarea:-webkit-autofill, +textarea:-webkit-autofill:hover textarea:-webkit-autofill:focus, +select:-webkit-autofill, +select:-webkit-autofill:hover, +select:-webkit-autofill:focus { + background: linear-gradient( + rgb(255 255 255 / 0%) 0%, + rgb(0 174 255 / 4%) 50%, + rgb(255 255 255 / 0%) 51%, + rgb(0 174 255 / 3%) 100% + ); + box-shadow: 0 0 0 1000px transparent inset; + transition: background-color 5000s ease-in-out 0s; + + -webkit-text-fill-color: var(--color-light-100); +}