mirror of
https://github.com/ershisan99/flashcards-example-project.git
synced 2025-12-16 20:59:27 +00:00
feat: rtk query + routing
feat: layout feat: page component
This commit is contained in:
@@ -18,11 +18,13 @@
|
||||
"@radix-ui/react-checkbox": "^1.0.4",
|
||||
"@radix-ui/react-label": "^2.0.2",
|
||||
"@radix-ui/react-radio-group": "^1.1.3",
|
||||
"@reduxjs/toolkit": "^2.0.1",
|
||||
"@storybook/theming": "^7.2.1",
|
||||
"clsx": "^2.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-hook-form": "^7.45.2",
|
||||
"react-redux": "^9.0.4",
|
||||
"react-router-dom": "^6.14.2",
|
||||
"react-toastify": "^9.1.3",
|
||||
"remeda": "^1.24.0",
|
||||
|
||||
79
pnpm-lock.yaml
generated
79
pnpm-lock.yaml
generated
@@ -20,6 +20,9 @@ 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)
|
||||
'@reduxjs/toolkit':
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1(react-redux@9.0.4)(react@18.2.0)
|
||||
'@storybook/theming':
|
||||
specifier: ^7.2.1
|
||||
version: 7.2.1(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -35,6 +38,9 @@ dependencies:
|
||||
react-hook-form:
|
||||
specifier: ^7.45.2
|
||||
version: 7.45.2(react@18.2.0)
|
||||
react-redux:
|
||||
specifier: ^9.0.4
|
||||
version: 9.0.4(@types/react@18.2.15)(react@18.2.0)(redux@5.0.0)
|
||||
react-router-dom:
|
||||
specifier: ^6.14.2
|
||||
version: 6.14.2(react-dom@18.2.0)(react@18.2.0)
|
||||
@@ -2672,6 +2678,25 @@ packages:
|
||||
dependencies:
|
||||
'@babel/runtime': 7.22.6
|
||||
|
||||
/@reduxjs/toolkit@2.0.1(react-redux@9.0.4)(react@18.2.0):
|
||||
resolution: {integrity: sha512-fxIjrR9934cmS8YXIGd9e7s1XRsEU++aFc9DVNMFMRTM5Vtsg2DCRMj21eslGtDt43IUf9bJL3h5bwUlZleibA==}
|
||||
peerDependencies:
|
||||
react: ^16.9.0 || ^17.0.0 || ^18
|
||||
react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-redux:
|
||||
optional: true
|
||||
dependencies:
|
||||
immer: 10.0.3
|
||||
react: 18.2.0
|
||||
react-redux: 9.0.4(@types/react@18.2.15)(react@18.2.0)(redux@5.0.0)
|
||||
redux: 5.0.0
|
||||
redux-thunk: 3.1.0(redux@5.0.0)
|
||||
reselect: 5.0.1
|
||||
dev: false
|
||||
|
||||
/@remix-run/router@1.7.2:
|
||||
resolution: {integrity: sha512-7Lcn7IqGMV+vizMPoEl5F0XDshcdDYtMI6uJLQdQz5CfZAwy3vvGKYSUk789qndt5dEC4HfSjviSYlSoHGL2+A==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -4073,6 +4098,10 @@ packages:
|
||||
resolution: {integrity: sha512-cputDpIbFgLUaGQn6Vqg3/YsJwxUwHLO13v3i5ouxT4lat0khip9AEWxtERujXV9wxIB1EyF97BSJFt6vpdI8g==}
|
||||
dev: true
|
||||
|
||||
/@types/use-sync-external-store@0.0.3:
|
||||
resolution: {integrity: sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==}
|
||||
dev: false
|
||||
|
||||
/@types/yargs-parser@21.0.0:
|
||||
resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
|
||||
dev: true
|
||||
@@ -6726,6 +6755,10 @@ packages:
|
||||
engines: {node: '>= 4'}
|
||||
dev: true
|
||||
|
||||
/immer@10.0.3:
|
||||
resolution: {integrity: sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A==}
|
||||
dev: false
|
||||
|
||||
/immutable@4.3.1:
|
||||
resolution: {integrity: sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==}
|
||||
dev: true
|
||||
@@ -8368,6 +8401,28 @@ packages:
|
||||
resolution: {integrity: sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==}
|
||||
dev: true
|
||||
|
||||
/react-redux@9.0.4(@types/react@18.2.15)(react@18.2.0)(redux@5.0.0):
|
||||
resolution: {integrity: sha512-9J1xh8sWO0vYq2sCxK2My/QO7MzUMRi3rpiILP/+tDr8krBHixC6JMM17fMK88+Oh3e4Ae6/sHIhNBgkUivwFA==}
|
||||
peerDependencies:
|
||||
'@types/react': ^18.2.25
|
||||
react: ^18.0
|
||||
react-native: '>=0.69'
|
||||
redux: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
react-native:
|
||||
optional: true
|
||||
redux:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.2.15
|
||||
'@types/use-sync-external-store': 0.0.3
|
||||
react: 18.2.0
|
||||
redux: 5.0.0
|
||||
use-sync-external-store: 1.2.0(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-refresh@0.14.0:
|
||||
resolution: {integrity: sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
@@ -8565,6 +8620,18 @@ packages:
|
||||
strip-indent: 4.0.0
|
||||
dev: true
|
||||
|
||||
/redux-thunk@3.1.0(redux@5.0.0):
|
||||
resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
|
||||
peerDependencies:
|
||||
redux: ^5.0.0
|
||||
dependencies:
|
||||
redux: 5.0.0
|
||||
dev: false
|
||||
|
||||
/redux@5.0.0:
|
||||
resolution: {integrity: sha512-blLIYmYetpZMET6Q6uCY7Jtl/Im5OBldy+vNPauA8vvsdqyt66oep4EUpAMWNHauTC6xa9JuRPhRB72rY82QGA==}
|
||||
dev: false
|
||||
|
||||
/regenerate-unicode-properties@10.1.0:
|
||||
resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -8649,6 +8716,10 @@ packages:
|
||||
engines: {node: '>=0.10.5'}
|
||||
dev: true
|
||||
|
||||
/reselect@5.0.1:
|
||||
resolution: {integrity: sha512-D72j2ubjgHpvuCiORWkOUxndHJrxDaSolheiz5CO+roz8ka97/4msh2E8F5qay4GawR5vzBt5MkbDHT+Rdy/Wg==}
|
||||
dev: false
|
||||
|
||||
/resolve-from@4.0.0:
|
||||
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
|
||||
engines: {node: '>=4'}
|
||||
@@ -9814,6 +9885,14 @@ packages:
|
||||
react: 18.2.0
|
||||
tslib: 2.6.1
|
||||
|
||||
/use-sync-external-store@1.2.0(react@18.2.0):
|
||||
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
dependencies:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
|
||||
14
src/App.tsx
14
src/App.tsx
@@ -1,3 +1,15 @@
|
||||
import { Provider } from 'react-redux'
|
||||
|
||||
import { Layout } from '@/components/ui/layout/layout.tsx'
|
||||
import { Router } from '@/router.tsx'
|
||||
import { store } from '@/services/store'
|
||||
|
||||
export function App() {
|
||||
return <div>Hello</div>
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<Layout>
|
||||
<Router />
|
||||
</Layout>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,63 +1,71 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width="44"
|
||||
height="44"
|
||||
viewBox="0 0 44 44"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<g filter="url(#filter0_d_5918_2450)">
|
||||
<rect x="10" y="8" width="24" height="24" rx="4" fill="#4C4C4C" />
|
||||
<g clipPath="url(#clip0_5918_2450)">
|
||||
<path
|
||||
d="M26.6666 25.3334H17.3333C17.1565 25.3334 16.9869 25.4036 16.8619 25.5286C16.7369 25.6537 16.6666 25.8232 16.6666 26C16.6666 26.1769 16.7369 26.3464 16.8619 26.4714C16.9869 26.5965 17.1565 26.6667 17.3333 26.6667H26.6666C26.8434 26.6667 27.013 26.5965 27.138 26.4714C27.2631 26.3464 27.3333 26.1769 27.3333 26C27.3333 25.8232 27.2631 25.6537 27.138 25.5286C27.013 25.4036 26.8434 25.3334 26.6666 25.3334Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M17.3333 24H17.3933L20.1733 23.7467C20.4778 23.7163 20.7626 23.5821 20.98 23.3667L26.98 17.3667C27.2128 17.1206 27.3387 16.7923 27.3299 16.4537C27.3212 16.115 27.1786 15.7937 26.9333 15.56L25.1066 13.7333C24.8682 13.5094 24.5558 13.3809 24.2288 13.3723C23.9019 13.3637 23.5831 13.4756 23.3333 13.6867L17.3333 19.6867C17.1178 19.904 16.9836 20.1888 16.9533 20.4933L16.6666 23.2733C16.6576 23.371 16.6703 23.4694 16.7037 23.5616C16.7371 23.6538 16.7905 23.7374 16.86 23.8067C16.9222 23.8684 16.9961 23.9173 17.0773 23.9505C17.1586 23.9837 17.2455 24.0005 17.3333 24ZM24.18 14.6667L26 16.4867L24.6666 17.7867L22.88 16L24.18 14.6667ZM18.2466 20.6067L22 16.88L23.8 18.68L20.0666 22.4133L18.0666 22.6L18.2466 20.6067Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
id="filter0_d_5918_2450"
|
||||
x="0"
|
||||
y="0"
|
||||
width="44"
|
||||
height="44"
|
||||
filterUnits="userSpaceOnUse"
|
||||
colorInterpolationFilters="sRGB"
|
||||
>
|
||||
<feFlood floodOpacity="0" result="BackgroundImageFix" />
|
||||
<feColorMatrix
|
||||
in="SourceAlpha"
|
||||
type="matrix"
|
||||
values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
|
||||
result="hardAlpha"
|
||||
/>
|
||||
<feOffset dy="2" />
|
||||
<feGaussianBlur stdDeviation="5" />
|
||||
<feColorMatrix
|
||||
type="matrix"
|
||||
values="0 0 0 0 0.429167 0 0 0 0 0.429167 0 0 0 0 0.429167 0 0 0 0.25 0"
|
||||
/>
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_5918_2450" />
|
||||
<feBlend
|
||||
mode="normal"
|
||||
in="SourceGraphic"
|
||||
in2="effect1_dropShadow_5918_2450"
|
||||
result="shape"
|
||||
/>
|
||||
</filter>
|
||||
<clipPath id="clip0_5918_2450">
|
||||
<rect width="16" height="16" fill="white" transform="translate(14 12)" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'44'}
|
||||
ref={ref}
|
||||
viewBox={'0 0 44 44'}
|
||||
width={'44'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g filter={'url(#filter0_d_5918_2450)'}>
|
||||
<rect fill={'#4C4C4C'} height={'24'} rx={'4'} width={'24'} x={'10'} y={'8'} />
|
||||
<g clipPath={'url(#clip0_5918_2450)'}>
|
||||
<path
|
||||
d={
|
||||
'M26.6666 25.3334H17.3333C17.1565 25.3334 16.9869 25.4036 16.8619 25.5286C16.7369 25.6537 16.6666 25.8232 16.6666 26C16.6666 26.1769 16.7369 26.3464 16.8619 26.4714C16.9869 26.5965 17.1565 26.6667 17.3333 26.6667H26.6666C26.8434 26.6667 27.013 26.5965 27.138 26.4714C27.2631 26.3464 27.3333 26.1769 27.3333 26C27.3333 25.8232 27.2631 25.6537 27.138 25.5286C27.013 25.4036 26.8434 25.3334 26.6666 25.3334Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M17.3333 24H17.3933L20.1733 23.7467C20.4778 23.7163 20.7626 23.5821 20.98 23.3667L26.98 17.3667C27.2128 17.1206 27.3387 16.7923 27.3299 16.4537C27.3212 16.115 27.1786 15.7937 26.9333 15.56L25.1066 13.7333C24.8682 13.5094 24.5558 13.3809 24.2288 13.3723C23.9019 13.3637 23.5831 13.4756 23.3333 13.6867L17.3333 19.6867C17.1178 19.904 16.9836 20.1888 16.9533 20.4933L16.6666 23.2733C16.6576 23.371 16.6703 23.4694 16.7037 23.5616C16.7371 23.6538 16.7905 23.7374 16.86 23.8067C16.9222 23.8684 16.9961 23.9173 17.0773 23.9505C17.1586 23.9837 17.2455 24.0005 17.3333 24ZM24.18 14.6667L26 16.4867L24.6666 17.7867L22.88 16L24.18 14.6667ZM18.2466 20.6067L22 16.88L23.8 18.68L20.0666 22.4133L18.0666 22.6L18.2466 20.6067Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter
|
||||
colorInterpolationFilters={'sRGB'}
|
||||
filterUnits={'userSpaceOnUse'}
|
||||
height={'44'}
|
||||
id={'filter0_d_5918_2450'}
|
||||
width={'44'}
|
||||
x={'0'}
|
||||
y={'0'}
|
||||
>
|
||||
<feFlood floodOpacity={'0'} result={'BackgroundImageFix'} />
|
||||
<feColorMatrix
|
||||
in={'SourceAlpha'}
|
||||
result={'hardAlpha'}
|
||||
type={'matrix'}
|
||||
values={'0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0'}
|
||||
/>
|
||||
<feOffset dy={'2'} />
|
||||
<feGaussianBlur stdDeviation={'5'} />
|
||||
<feColorMatrix
|
||||
type={'matrix'}
|
||||
values={'0 0 0 0 0.429167 0 0 0 0 0.429167 0 0 0 0 0.429167 0 0 0 0.25 0'}
|
||||
/>
|
||||
<feBlend
|
||||
in2={'BackgroundImageFix'}
|
||||
mode={'normal'}
|
||||
result={'effect1_dropShadow_5918_2450'}
|
||||
/>
|
||||
<feBlend
|
||||
in={'SourceGraphic'}
|
||||
in2={'effect1_dropShadow_5918_2450'}
|
||||
mode={'normal'}
|
||||
result={'shape'}
|
||||
/>
|
||||
</filter>
|
||||
<clipPath id={'clip0_5918_2450'}>
|
||||
<rect fill={'white'} height={'16'} transform={'translate(14 12)'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
@@ -1,19 +1,21 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={18}
|
||||
height={18}
|
||||
viewBox="0 0 18 18"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d="M16 0H2a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V2a2 2 0 00-2-2zM7 14L2 9l1.41-1.41L7 11.17l7.59-7.59L16 5l-9 9z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={18}
|
||||
ref={ref}
|
||||
viewBox={'0 0 18 18'}
|
||||
width={18}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d={
|
||||
'M16 0H2a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2V2a2 2 0 00-2-2zM7 14L2 9l1.41-1.41L7 11.17l7.59-7.59L16 5l-9 9z'
|
||||
}
|
||||
fill={'currentColor'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
@@ -1,26 +1,28 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const ChevronUp = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width={12}
|
||||
height={12}
|
||||
viewBox="0 0 12 12"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath="url(#clip0_9209_3250)">
|
||||
<path
|
||||
d="M9.77084 7.25705C9.77107 7.37388 9.73039 7.4871 9.65584 7.57705C9.61387 7.62768 9.56232 7.66953 9.50415 7.70021C9.44597 7.73089 9.38232 7.74978 9.31683 7.75582C9.25134 7.76186 9.18531 7.75492 9.1225 7.7354C9.0597 7.71588 9.00137 7.68416 8.95084 7.64205L6.27084 5.40205L3.58584 7.56205C3.5347 7.60359 3.47585 7.6346 3.41268 7.65332C3.34951 7.67203 3.28327 7.67808 3.21775 7.67111C3.15224 7.66414 3.08875 7.64429 3.03093 7.61271C2.97311 7.58112 2.92211 7.53842 2.88084 7.48705C2.83533 7.43532 2.80099 7.37474 2.78 7.30911C2.759 7.24348 2.7518 7.17421 2.75884 7.10567C2.76589 7.03712 2.78702 6.97077 2.82092 6.91078C2.85482 6.85079 2.90076 6.79845 2.95584 6.75705L5.95584 4.34205C6.04531 4.26851 6.15753 4.22831 6.27334 4.22831C6.38916 4.22831 6.50138 4.26851 6.59084 4.34205L9.59084 6.84205C9.65135 6.89221 9.69918 6.95593 9.73046 7.02803C9.76173 7.10014 9.77557 7.1786 9.77084 7.25705Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_9209_3250">
|
||||
<rect width={12} height={12} fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={12}
|
||||
ref={ref}
|
||||
viewBox={'0 0 12 12'}
|
||||
width={12}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_9209_3250)'}>
|
||||
<path
|
||||
d={
|
||||
'M9.77084 7.25705C9.77107 7.37388 9.73039 7.4871 9.65584 7.57705C9.61387 7.62768 9.56232 7.66953 9.50415 7.70021C9.44597 7.73089 9.38232 7.74978 9.31683 7.75582C9.25134 7.76186 9.18531 7.75492 9.1225 7.7354C9.0597 7.71588 9.00137 7.68416 8.95084 7.64205L6.27084 5.40205L3.58584 7.56205C3.5347 7.60359 3.47585 7.6346 3.41268 7.65332C3.34951 7.67203 3.28327 7.67808 3.21775 7.67111C3.15224 7.66414 3.08875 7.64429 3.03093 7.61271C2.97311 7.58112 2.92211 7.53842 2.88084 7.48705C2.83533 7.43532 2.80099 7.37474 2.78 7.30911C2.759 7.24348 2.7518 7.17421 2.75884 7.10567C2.76589 7.03712 2.78702 6.97077 2.82092 6.91078C2.85482 6.85079 2.90076 6.79845 2.95584 6.75705L5.95584 4.34205C6.04531 4.26851 6.15753 4.22831 6.27334 4.22831C6.38916 4.22831 6.50138 4.26851 6.59084 4.34205L9.59084 6.84205C9.65135 6.89221 9.69918 6.95593 9.73046 7.02803C9.76173 7.10014 9.77557 7.1786 9.77084 7.25705Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_9209_3250'}>
|
||||
<rect fill={'white'} height={12} width={12} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(ChevronUp)
|
||||
const Memo = memo(ForwardRef)
|
||||
|
||||
@@ -1,29 +1,37 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
|
||||
<g clipPath="url(#clip0_9883_2381)">
|
||||
<path
|
||||
d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_9883_2381">
|
||||
<rect width="24" height="24" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'24'}
|
||||
ref={ref}
|
||||
viewBox={'0 0 24 24'}
|
||||
width={'24'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'24'}
|
||||
viewBox={'0 0 24 24'}
|
||||
width={'24'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
>
|
||||
<g clipPath={'url(#clip0_9883_2381)'}>
|
||||
<path
|
||||
d={
|
||||
'M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_9883_2381'}>
|
||||
<rect fill={'white'} height={'24'} width={'24'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
</svg>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
33
src/assets/icons/edit-2-outline.tsx
Normal file
33
src/assets/icons/edit-2-outline.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { SVGProps } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_28366_3239)'}>
|
||||
<path
|
||||
d={
|
||||
'M12.6666 13.3334H3.33329C3.15648 13.3334 2.98691 13.4036 2.86189 13.5286C2.73686 13.6537 2.66663 13.8232 2.66663 14C2.66663 14.1769 2.73686 14.3464 2.86189 14.4714C2.98691 14.5965 3.15648 14.6667 3.33329 14.6667H12.6666C12.8434 14.6667 13.013 14.5965 13.138 14.4714C13.2631 14.3464 13.3333 14.1769 13.3333 14C13.3333 13.8232 13.2631 13.6537 13.138 13.5286C13.013 13.4036 12.8434 13.3334 12.6666 13.3334Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M3.33329 12H3.39329L6.17329 11.7467C6.47782 11.7163 6.76264 11.5821 6.97995 11.3667L12.98 5.36665C13.2128 5.12063 13.3387 4.79233 13.3299 4.45368C13.3212 4.11503 13.1786 3.79366 12.9333 3.55999L11.1066 1.73332C10.8682 1.50938 10.5558 1.38089 10.2288 1.37229C9.90187 1.36368 9.58314 1.47557 9.33329 1.68665L3.33329 7.68665C3.1178 7.90396 2.98362 8.18879 2.95329 8.49332L2.66662 11.2733C2.65764 11.371 2.67031 11.4694 2.70373 11.5616C2.73715 11.6538 2.79049 11.7374 2.85995 11.8067C2.92225 11.8684 2.99612 11.9173 3.07735 11.9505C3.15857 11.9837 3.24555 12.0005 3.33329 12ZM10.18 2.66665L12 4.48665L10.6666 5.78665L8.87995 3.99999L10.18 2.66665ZM4.24662 8.60665L7.99995 4.87999L9.79995 6.67999L6.06662 10.4133L4.06662 10.6L4.24662 8.60665Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_28366_3239'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponent
|
||||
@@ -1,30 +1,34 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath="url(#clip0_5918_2436)">
|
||||
<path
|
||||
d="M12.6666 13.3334H3.33329C3.15648 13.3334 2.98691 13.4036 2.86189 13.5286C2.73686 13.6537 2.66663 13.8232 2.66663 14C2.66663 14.1769 2.73686 14.3464 2.86189 14.4714C2.98691 14.5965 3.15648 14.6667 3.33329 14.6667H12.6666C12.8434 14.6667 13.013 14.5965 13.138 14.4714C13.2631 14.3464 13.3333 14.1769 13.3333 14C13.3333 13.8232 13.2631 13.6537 13.138 13.5286C13.013 13.4036 12.8434 13.3334 12.6666 13.3334Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M3.33329 12H3.39329L6.17329 11.7467C6.47782 11.7163 6.76264 11.5821 6.97995 11.3667L12.98 5.36665C13.2128 5.12063 13.3387 4.79233 13.3299 4.45368C13.3212 4.11503 13.1786 3.79366 12.9333 3.55999L11.1066 1.73332C10.8682 1.50938 10.5558 1.38089 10.2288 1.37229C9.90187 1.36368 9.58314 1.47557 9.33329 1.68665L3.33329 7.68665C3.1178 7.90396 2.98362 8.18879 2.95329 8.49332L2.66662 11.2733C2.65764 11.371 2.67031 11.4694 2.70373 11.5616C2.73715 11.6538 2.79049 11.7374 2.85995 11.8067C2.92225 11.8684 2.99612 11.9173 3.07735 11.9505C3.15857 11.9837 3.24555 12.0005 3.33329 12ZM10.18 2.66665L12 4.48665L10.6666 5.78665L8.87995 3.99999L10.18 2.66665ZM4.24662 8.60665L7.99995 4.87999L9.79995 6.67999L6.06662 10.4133L4.06662 10.6L4.24662 8.60665Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_5918_2436">
|
||||
<rect width="16" height="16" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
ref={ref}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_5918_2436)'}>
|
||||
<path
|
||||
d={
|
||||
'M12.6666 13.3334H3.33329C3.15648 13.3334 2.98691 13.4036 2.86189 13.5286C2.73686 13.6537 2.66663 13.8232 2.66663 14C2.66663 14.1769 2.73686 14.3464 2.86189 14.4714C2.98691 14.5965 3.15648 14.6667 3.33329 14.6667H12.6666C12.8434 14.6667 13.013 14.5965 13.138 14.4714C13.2631 14.3464 13.3333 14.1769 13.3333 14C13.3333 13.8232 13.2631 13.6537 13.138 13.5286C13.013 13.4036 12.8434 13.3334 12.6666 13.3334Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M3.33329 12H3.39329L6.17329 11.7467C6.47782 11.7163 6.76264 11.5821 6.97995 11.3667L12.98 5.36665C13.2128 5.12063 13.3387 4.79233 13.3299 4.45368C13.3212 4.11503 13.1786 3.79366 12.9333 3.55999L11.1066 1.73332C10.8682 1.50938 10.5558 1.38089 10.2288 1.37229C9.90187 1.36368 9.58314 1.47557 9.33329 1.68665L3.33329 7.68665C3.1178 7.90396 2.98362 8.18879 2.95329 8.49332L2.66662 11.2733C2.65764 11.371 2.67031 11.4694 2.70373 11.5616C2.73715 11.6538 2.79049 11.7374 2.85995 11.8067C2.92225 11.8684 2.99612 11.9173 3.07735 11.9505C3.15857 11.9837 3.24555 12.0005 3.33329 12ZM10.18 2.66665L12 4.48665L10.6666 5.78665L8.87995 3.99999L10.18 2.66665ZM4.24662 8.60665L7.99995 4.87999L9.79995 6.67999L6.06662 10.4133L4.06662 10.6L4.24662 8.60665Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_5918_2436'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
const Memo = memo(ForwardRef)
|
||||
|
||||
@@ -1,73 +1,100 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={96}
|
||||
height={96}
|
||||
fill="none"
|
||||
viewBox="0 0 96 96"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="#8C61FF"
|
||||
fillOpacity={0.05}
|
||||
stroke="#BEA6FF"
|
||||
d="M95.5 48c0 26.234-21.266 47.5-47.5 47.5C21.767 95.5.5 74.234.5 48 .5 21.767 21.767.5 48 .5 74.234.5 95.5 21.767 95.5 48z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M77.889 54.454a.651.651 0 0 1-.643-.643v-9.24a.643.643 0 0 1 1.285 0v9.25a.643.643 0 0 1-.641.633zM77.889 41.777a.643.643 0 0 1-.643-.643V39.24a.643.643 0 0 1 1.285 0v1.903a.634.634 0 0 1-.641.634zM25.786 32.503h-3.559a.668.668 0 0 1 0-1.335h3.56a.667.667 0 0 1 0 1.335z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M24.007 34.282a.668.668 0 0 1-.667-.667v-3.559a.668.668 0 0 1 1.335 0v3.56c0 .367-.3.666-.668.666zM36.857 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM31.714 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM26.571 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715z"
|
||||
/>
|
||||
<path fill="#333" d="M47.864 23.242l-24.1 19.799 24.1 19.808 24.1-19.808-24.1-19.8z" />
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M47.865 63.544a.667.667 0 0 1-.417-.195l-24.1-19.808a.698.698 0 0 1-.183-.833.725.725 0 0 1 .183-.242l24.1-19.799a.695.695 0 0 1 .926 0l24.1 19.799a.725.725 0 0 1 .25.537.695.695 0 0 1-.25.538l-24.1 19.808a.668.668 0 0 1-.51.195zM24.859 43.04l23.006 18.91L70.87 43.04l-23.006-18.9-23.006 18.9z"
|
||||
/>
|
||||
<path fill="#333" d="M65.013 28.803H30.717v40.784h34.296V28.803z" />
|
||||
<path fill="#333" d="M55.41 40.853l-11.716 9.63v19.104h21.319V40.853H55.41z" />
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M65.059 70.282H30.763a.704.704 0 0 1-.695-.695V28.803a.695.695 0 0 1 .695-.677H65.06a.695.695 0 0 1 .695.696v40.784a.705.705 0 0 1-.695.676zM31.412 68.91h32.905V29.517H31.412V68.91z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M58.987 35.06H48.17a.695.695 0 0 1 0-1.39h10.817a.696.696 0 0 1 0 1.39zM44.463 35.06h-7.721a.696.696 0 0 1 0-1.39h7.72a.696.696 0 0 1 0 1.39zM58.987 39.694h-7.11a.695.695 0 0 1 0-1.39h7.11a.695.695 0 1 1 0 1.39zM48.17 39.694H36.742a.695.695 0 0 1 0-1.39H48.17a.695.695 0 1 1 0 1.39zM58.988 44.329H46.317a.696.696 0 0 1 0-1.39h12.67a.696.696 0 0 1 0 1.39zM42.609 44.329h-5.867a.696.696 0 0 1 0-1.39h5.867a.696.696 0 0 1 0 1.39zM58.987 48.964h-6.182a.695.695 0 0 1 0-1.39h6.182a.695.695 0 1 1 0 1.39zM49.097 48.964H36.742a.695.695 0 0 1 0-1.39h12.355a.695.695 0 1 1 0 1.39zM54.047 53.598H41.682a.695.695 0 1 1 0-1.39h12.365a.695.695 0 1 1 0 1.39z"
|
||||
/>
|
||||
<path
|
||||
fill="#333"
|
||||
d="M23.765 43.04v26.547l16.147-13.273L23.765 43.04zM55.818 56.314l16.146 13.273V43.04L55.818 56.315z"
|
||||
/>
|
||||
<path
|
||||
fill="#333"
|
||||
d="M47.864 62.849l-7.952-6.535-16.147 13.273h48.2L55.816 56.314l-7.953 6.535z"
|
||||
/>
|
||||
<path
|
||||
fill="#333"
|
||||
d="M28.4 50.493v15.284l9.297-7.637-9.297-7.647zM63.196 57.88l8.768 7.212V50.678l-8.768 7.202z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M23.765 70.282a.67.67 0 0 1-.296-.074.686.686 0 0 1-.399-.62V43.04a.685.685 0 0 1 .399-.62.695.695 0 0 1 .741.083l16.147 13.273a.704.704 0 0 1 0 1.075L24.21 70.115a.686.686 0 0 1-.445.167zm.695-25.768v23.6l14.358-11.8-14.358-11.8z"
|
||||
/>
|
||||
<path fill="#333" d="M60.424 60.095l-10.15 8.343-7.08-5.821-8.473 6.97h37.243l-11.54-9.492z" />
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M71.964 70.282a.686.686 0 0 1-.445-.167L55.373 56.861a.703.703 0 0 1 0-1.076l16.174-13.282a.696.696 0 0 1 .742-.084.687.687 0 0 1 .398.621v26.547a.686.686 0 0 1-.398.621.668.668 0 0 1-.325.074zM56.911 56.314l14.358 11.8v-23.6l-14.358 11.8z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M71.964 70.282h-48.2a.704.704 0 0 1-.657-.463.705.705 0 0 1 .213-.77l16.147-13.273a.695.695 0 0 1 .927 0l7.508 6.173 7.508-6.174a.695.695 0 0 1 .927 0L72.483 69.05a.705.705 0 0 1 .213.77.704.704 0 0 1-.732.463zm-46.262-1.371h44.325L55.79 57.212l-7.508 6.173a.695.695 0 0 1-.927 0l-7.508-6.173L25.702 68.91zM46.358 75.36h-3.56a.668.668 0 0 1 0-1.335h3.56a.668.668 0 0 1 0 1.335z"
|
||||
/>
|
||||
<path
|
||||
fill="#BEA6FF"
|
||||
d="M44.579 77.14a.668.668 0 0 1-.668-.668v-3.559a.668.668 0 0 1 1.335 0v3.56a.667.667 0 0 1-.667.666z"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={96}
|
||||
ref={ref}
|
||||
viewBox={'0 0 96 96'}
|
||||
width={96}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d={
|
||||
'M95.5 48c0 26.234-21.266 47.5-47.5 47.5C21.767 95.5.5 74.234.5 48 .5 21.767 21.767.5 48 .5 74.234.5 95.5 21.767 95.5 48z'
|
||||
}
|
||||
fill={'#8C61FF'}
|
||||
fillOpacity={0.05}
|
||||
stroke={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M77.889 54.454a.651.651 0 0 1-.643-.643v-9.24a.643.643 0 0 1 1.285 0v9.25a.643.643 0 0 1-.641.633zM77.889 41.777a.643.643 0 0 1-.643-.643V39.24a.643.643 0 0 1 1.285 0v1.903a.634.634 0 0 1-.641.634zM25.786 32.503h-3.559a.668.668 0 0 1 0-1.335h3.56a.667.667 0 0 1 0 1.335z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M24.007 34.282a.668.668 0 0 1-.667-.667v-3.559a.668.668 0 0 1 1.335 0v3.56c0 .367-.3.666-.668.666zM36.857 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM31.714 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715zM26.571 73.714a.857.857 0 1 1 0 1.715.857.857 0 0 1 0-1.715z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path d={'M47.864 23.242l-24.1 19.799 24.1 19.808 24.1-19.808-24.1-19.8z'} fill={'#333'} />
|
||||
<path
|
||||
d={
|
||||
'M47.865 63.544a.667.667 0 0 1-.417-.195l-24.1-19.808a.698.698 0 0 1-.183-.833.725.725 0 0 1 .183-.242l24.1-19.799a.695.695 0 0 1 .926 0l24.1 19.799a.725.725 0 0 1 .25.537.695.695 0 0 1-.25.538l-24.1 19.808a.668.668 0 0 1-.51.195zM24.859 43.04l23.006 18.91L70.87 43.04l-23.006-18.9-23.006 18.9z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path d={'M65.013 28.803H30.717v40.784h34.296V28.803z'} fill={'#333'} />
|
||||
<path d={'M55.41 40.853l-11.716 9.63v19.104h21.319V40.853H55.41z'} fill={'#333'} />
|
||||
<path
|
||||
d={
|
||||
'M65.059 70.282H30.763a.704.704 0 0 1-.695-.695V28.803a.695.695 0 0 1 .695-.677H65.06a.695.695 0 0 1 .695.696v40.784a.705.705 0 0 1-.695.676zM31.412 68.91h32.905V29.517H31.412V68.91z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M58.987 35.06H48.17a.695.695 0 0 1 0-1.39h10.817a.696.696 0 0 1 0 1.39zM44.463 35.06h-7.721a.696.696 0 0 1 0-1.39h7.72a.696.696 0 0 1 0 1.39zM58.987 39.694h-7.11a.695.695 0 0 1 0-1.39h7.11a.695.695 0 1 1 0 1.39zM48.17 39.694H36.742a.695.695 0 0 1 0-1.39H48.17a.695.695 0 1 1 0 1.39zM58.988 44.329H46.317a.696.696 0 0 1 0-1.39h12.67a.696.696 0 0 1 0 1.39zM42.609 44.329h-5.867a.696.696 0 0 1 0-1.39h5.867a.696.696 0 0 1 0 1.39zM58.987 48.964h-6.182a.695.695 0 0 1 0-1.39h6.182a.695.695 0 1 1 0 1.39zM49.097 48.964H36.742a.695.695 0 0 1 0-1.39h12.355a.695.695 0 1 1 0 1.39zM54.047 53.598H41.682a.695.695 0 1 1 0-1.39h12.365a.695.695 0 1 1 0 1.39z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M23.765 43.04v26.547l16.147-13.273L23.765 43.04zM55.818 56.314l16.146 13.273V43.04L55.818 56.315z'
|
||||
}
|
||||
fill={'#333'}
|
||||
/>
|
||||
<path
|
||||
d={'M47.864 62.849l-7.952-6.535-16.147 13.273h48.2L55.816 56.314l-7.953 6.535z'}
|
||||
fill={'#333'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M28.4 50.493v15.284l9.297-7.637-9.297-7.647zM63.196 57.88l8.768 7.212V50.678l-8.768 7.202z'
|
||||
}
|
||||
fill={'#333'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M23.765 70.282a.67.67 0 0 1-.296-.074.686.686 0 0 1-.399-.62V43.04a.685.685 0 0 1 .399-.62.695.695 0 0 1 .741.083l16.147 13.273a.704.704 0 0 1 0 1.075L24.21 70.115a.686.686 0 0 1-.445.167zm.695-25.768v23.6l14.358-11.8-14.358-11.8z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={'M60.424 60.095l-10.15 8.343-7.08-5.821-8.473 6.97h37.243l-11.54-9.492z'}
|
||||
fill={'#333'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M71.964 70.282a.686.686 0 0 1-.445-.167L55.373 56.861a.703.703 0 0 1 0-1.076l16.174-13.282a.696.696 0 0 1 .742-.084.687.687 0 0 1 .398.621v26.547a.686.686 0 0 1-.398.621.668.668 0 0 1-.325.074zM56.911 56.314l14.358 11.8v-23.6l-14.358 11.8z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M71.964 70.282h-48.2a.704.704 0 0 1-.657-.463.705.705 0 0 1 .213-.77l16.147-13.273a.695.695 0 0 1 .927 0l7.508 6.173 7.508-6.174a.695.695 0 0 1 .927 0L72.483 69.05a.705.705 0 0 1 .213.77.704.704 0 0 1-.732.463zm-46.262-1.371h44.325L55.79 57.212l-7.508 6.173a.695.695 0 0 1-.927 0l-7.508-6.173L25.702 68.91zM46.358 75.36h-3.56a.668.668 0 0 1 0-1.335h3.56a.668.668 0 0 1 0 1.335z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M44.579 77.14a.668.668 0 0 1-.668-.668v-3.559a.668.668 0 0 1 1.335 0v3.56a.667.667 0 0 1-.667.666z'
|
||||
}
|
||||
fill={'#BEA6FF'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="#fff"
|
||||
fillRule="evenodd"
|
||||
d="M12 4.5C7 4.5 2.73 7.6 1 12a11.83 11.83 0 0 0 22 0c-1.73-4.39-6-7.5-11-7.5zM12 17a5 5 0 1 1 0-10 5 5 0 0 1 0 10zm0-8a3 3 0 1 0 0 6 3 3 0 0 0 0-6z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={20}
|
||||
ref={ref}
|
||||
viewBox={'0 0 24 24'}
|
||||
width={20}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
clipRule={'evenodd'}
|
||||
d={
|
||||
'M12 4.5C7 4.5 2.73 7.6 1 12a11.83 11.83 0 0 0 22 0c-1.73-4.39-6-7.5-11-7.5zM12 17a5 5 0 1 1 0-10 5 5 0 0 1 0 10zm0-8a3 3 0 1 0 0 6 3 3 0 0 0 0-6z'
|
||||
}
|
||||
fill={'#fff'}
|
||||
fillRule={'evenodd'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
export { default as Eye } from './eye'
|
||||
export { default as VisibilityOff } from './visibility-off'
|
||||
export { default as Check } from './check'
|
||||
export { default as Email } from './email'
|
||||
export { default as Camera } from './camera'
|
||||
export { default as Logout } from './logout'
|
||||
export { default as Edit } from './edit'
|
||||
export { default as Logo } from './logo'
|
||||
export { default as PersonOutline } from './person-outline'
|
||||
export { default as Check } from './check'
|
||||
export { default as ChevronUp } from './chevron-up'
|
||||
export { default as Close } from './close'
|
||||
export { default as Edit } from './edit'
|
||||
export { default as Edit2Outline } from './edit-2-outline'
|
||||
export { default as Email } from './email'
|
||||
export { default as Eye } from './eye'
|
||||
export { default as KeyboardArrowLeft } from './keyboard-arrow-left'
|
||||
export { default as KeyboardArrowRight } from './keyboard-arrow-right'
|
||||
export { default as Logo } from './logo'
|
||||
export { default as Logout } from './logout'
|
||||
export { default as PersonOutline } from './person-outline'
|
||||
export { default as PlayCircleOutline } from './play-circle-outline'
|
||||
export { default as Search } from './search'
|
||||
export { default as TrashOutline } from './trash-outline'
|
||||
export { default as VisibilityOff } from './visibility-off'
|
||||
|
||||
29
src/assets/icons/keyboard-arrow-left.tsx
Normal file
29
src/assets/icons/keyboard-arrow-left.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
ref={ref}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_5928_3055)'}>
|
||||
<path
|
||||
d={
|
||||
'M10.2733 11.06L7.21998 8L10.2733 4.94L9.33331 4L5.33331 8L9.33331 12L10.2733 11.06Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_5928_3055'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
export default memo(ForwardRef)
|
||||
29
src/assets/icons/keyboard-arrow-right.tsx
Normal file
29
src/assets/icons/keyboard-arrow-right.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
ref={ref}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_5928_3027)'}>
|
||||
<path
|
||||
d={
|
||||
'M5.72665 11.06L8.77999 8L5.72665 4.94L6.66665 4L10.6667 8L6.66665 12L5.72665 11.06Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_5928_3027'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
export default memo(ForwardRef)
|
||||
@@ -1,30 +1,34 @@
|
||||
import { SVGProps } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={157}
|
||||
height={36}
|
||||
fill="none"
|
||||
viewBox="0 0 157 36"
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="#fff"
|
||||
d="M70.99 24.72a7.34 7.34 0 0 1-3.5-.83 6.43 6.43 0 0 1-2.44-2.33c-.6-1-.89-2.13-.89-3.38s.3-2.37.89-3.36c.6-1 1.41-1.77 2.45-2.32a7.25 7.25 0 0 1 3.5-.85c1.1 0 2.08.19 2.96.57.89.39 1.63.94 2.23 1.66l-1.87 1.74a4.02 4.02 0 0 0-3.17-1.48c-.78 0-1.48.17-2.09.52-.6.34-1.09.81-1.44 1.43-.33.61-.5 1.3-.5 2.1 0 .77.17 1.47.5 2.09.35.6.83 1.1 1.44 1.44.61.34 1.31.5 2.1.5a4 4 0 0 0 3.16-1.5l1.87 1.74c-.6.73-1.34 1.3-2.23 1.68a7.4 7.4 0 0 1-2.97.58zM83.66 24.72c-1.8 0-3.2-.5-4.22-1.5-1-1-1.5-2.43-1.5-4.28v-7.08h2.93v6.97c0 2.26.93 3.4 2.8 3.4.92 0 1.61-.28 2.1-.82.47-.55.71-1.41.71-2.58v-6.97h2.89v7.08c0 1.85-.5 3.28-1.52 4.28-1 1-2.4 1.5-4.2 1.5zM101.5 17.93a3.13 3.13 0 0 1 2.3 3.12c0 1.1-.42 1.96-1.29 2.56-.84.6-2.09.9-3.73.9h-6.52V11.86h6.16c1.53 0 2.7.3 3.53.89a2.8 2.8 0 0 1 1.24 2.4 3.04 3.04 0 0 1-1.68 2.78zm-6.35-3.86v2.97h2.9c.72 0 1.26-.12 1.63-.38.38-.25.56-.62.56-1.11 0-.5-.18-.86-.56-1.1a2.92 2.92 0 0 0-1.63-.38h-2.9zm3.4 8.23c.77 0 1.34-.13 1.73-.38.4-.25.6-.65.6-1.18 0-1.04-.78-1.57-2.33-1.57h-3.4v3.13h3.4zM114.32 21.8h-5.85l-1.12 2.7h-2.99l5.62-12.64h2.88l5.64 12.64h-3.07l-1.11-2.7zm-.92-2.23l-2-4.84-2 4.84h4zM121.78 14.25h-4.03v-2.39h10.98v2.39h-4.03V24.5h-2.92V14.25zM136.23 24.72a7.4 7.4 0 0 1-3.55-.85 6.39 6.39 0 0 1-2.47-2.33 6.5 6.5 0 0 1-.88-3.36 6.34 6.34 0 0 1 3.35-5.69 7.4 7.4 0 0 1 3.55-.84c1.3 0 2.48.28 3.53.85a6.35 6.35 0 0 1 3.37 5.68 6.4 6.4 0 0 1-.9 3.36 6.4 6.4 0 0 1-2.47 2.33 7.29 7.29 0 0 1-3.53.85zm0-2.5a3.69 3.69 0 0 0 3.42-1.95c.35-.6.52-1.3.52-2.09 0-.78-.17-1.48-.52-2.1a3.56 3.56 0 0 0-1.4-1.42 3.94 3.94 0 0 0-2.02-.52 3.94 3.94 0 0 0-3.44 1.95c-.34.61-.5 1.3-.5 2.1 0 .77.16 1.47.5 2.09a3.82 3.82 0 0 0 3.44 1.94zM153.35 24.5l-2.43-3.52H148.24v3.52h-2.92V11.86h5.45c1.12 0 2.09.19 2.9.56.83.38 1.47.9 1.91 1.6.44.68.67 1.49.67 2.43a4.3 4.3 0 0 1-.69 2.44 4.25 4.25 0 0 1-1.9 1.55l2.82 4.06h-3.13zm-.06-8.05c0-.71-.22-1.25-.68-1.63-.45-.38-1.11-.57-1.99-.57h-2.36v4.4h2.37c.88 0 1.54-.2 2-.58a2 2 0 0 0 .68-1.62zM0 11.88h2.91v12.6H0v-12.6zM8.5 14.25H4.49v-2.37h10.97v2.37h-4.03v10.22H8.5V14.25zM33.74 11.88h2.92v12.6h-2.92v-12.6zM51.2 11.88v12.6h-2.39l-6.28-7.65v7.64h-2.88v-12.6h2.41l6.27 7.65v-7.64h2.88z"
|
||||
/>
|
||||
<path
|
||||
fill="#FF0808"
|
||||
fillRule="evenodd"
|
||||
d="M34.99 6.53a1.96 1.96 0 1 1 0 3.93 1.96 1.96 0 0 1 0-3.93z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
<path
|
||||
fill="#fff"
|
||||
fillRule="evenodd"
|
||||
d="M19.5 16.04A2 2 0 0 1 21.5 18a2 2 0 0 1-2 1.96A2 2 0 0 1 17.46 18a2 2 0 0 1 2.02-1.96zM42.48 34.5a16.5 16.5 0 1 0 0-33 16.5 16.5 0 0 0 0 33zm0 1.5a18 18 0 1 0 0-36 18 18 0 0 0 0 36z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={36}
|
||||
viewBox={'0 0 157 36'}
|
||||
width={157}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d={
|
||||
'M70.99 24.72a7.34 7.34 0 0 1-3.5-.83 6.43 6.43 0 0 1-2.44-2.33c-.6-1-.89-2.13-.89-3.38s.3-2.37.89-3.36c.6-1 1.41-1.77 2.45-2.32a7.25 7.25 0 0 1 3.5-.85c1.1 0 2.08.19 2.96.57.89.39 1.63.94 2.23 1.66l-1.87 1.74a4.02 4.02 0 0 0-3.17-1.48c-.78 0-1.48.17-2.09.52-.6.34-1.09.81-1.44 1.43-.33.61-.5 1.3-.5 2.1 0 .77.17 1.47.5 2.09.35.6.83 1.1 1.44 1.44.61.34 1.31.5 2.1.5a4 4 0 0 0 3.16-1.5l1.87 1.74c-.6.73-1.34 1.3-2.23 1.68a7.4 7.4 0 0 1-2.97.58zM83.66 24.72c-1.8 0-3.2-.5-4.22-1.5-1-1-1.5-2.43-1.5-4.28v-7.08h2.93v6.97c0 2.26.93 3.4 2.8 3.4.92 0 1.61-.28 2.1-.82.47-.55.71-1.41.71-2.58v-6.97h2.89v7.08c0 1.85-.5 3.28-1.52 4.28-1 1-2.4 1.5-4.2 1.5zM101.5 17.93a3.13 3.13 0 0 1 2.3 3.12c0 1.1-.42 1.96-1.29 2.56-.84.6-2.09.9-3.73.9h-6.52V11.86h6.16c1.53 0 2.7.3 3.53.89a2.8 2.8 0 0 1 1.24 2.4 3.04 3.04 0 0 1-1.68 2.78zm-6.35-3.86v2.97h2.9c.72 0 1.26-.12 1.63-.38.38-.25.56-.62.56-1.11 0-.5-.18-.86-.56-1.1a2.92 2.92 0 0 0-1.63-.38h-2.9zm3.4 8.23c.77 0 1.34-.13 1.73-.38.4-.25.6-.65.6-1.18 0-1.04-.78-1.57-2.33-1.57h-3.4v3.13h3.4zM114.32 21.8h-5.85l-1.12 2.7h-2.99l5.62-12.64h2.88l5.64 12.64h-3.07l-1.11-2.7zm-.92-2.23l-2-4.84-2 4.84h4zM121.78 14.25h-4.03v-2.39h10.98v2.39h-4.03V24.5h-2.92V14.25zM136.23 24.72a7.4 7.4 0 0 1-3.55-.85 6.39 6.39 0 0 1-2.47-2.33 6.5 6.5 0 0 1-.88-3.36 6.34 6.34 0 0 1 3.35-5.69 7.4 7.4 0 0 1 3.55-.84c1.3 0 2.48.28 3.53.85a6.35 6.35 0 0 1 3.37 5.68 6.4 6.4 0 0 1-.9 3.36 6.4 6.4 0 0 1-2.47 2.33 7.29 7.29 0 0 1-3.53.85zm0-2.5a3.69 3.69 0 0 0 3.42-1.95c.35-.6.52-1.3.52-2.09 0-.78-.17-1.48-.52-2.1a3.56 3.56 0 0 0-1.4-1.42 3.94 3.94 0 0 0-2.02-.52 3.94 3.94 0 0 0-3.44 1.95c-.34.61-.5 1.3-.5 2.1 0 .77.16 1.47.5 2.09a3.82 3.82 0 0 0 3.44 1.94zM153.35 24.5l-2.43-3.52H148.24v3.52h-2.92V11.86h5.45c1.12 0 2.09.19 2.9.56.83.38 1.47.9 1.91 1.6.44.68.67 1.49.67 2.43a4.3 4.3 0 0 1-.69 2.44 4.25 4.25 0 0 1-1.9 1.55l2.82 4.06h-3.13zm-.06-8.05c0-.71-.22-1.25-.68-1.63-.45-.38-1.11-.57-1.99-.57h-2.36v4.4h2.37c.88 0 1.54-.2 2-.58a2 2 0 0 0 .68-1.62zM0 11.88h2.91v12.6H0v-12.6zM8.5 14.25H4.49v-2.37h10.97v2.37h-4.03v10.22H8.5V14.25zM33.74 11.88h2.92v12.6h-2.92v-12.6zM51.2 11.88v12.6h-2.39l-6.28-7.65v7.64h-2.88v-12.6h2.41l6.27 7.65v-7.64h2.88z'
|
||||
}
|
||||
fill={'#fff'}
|
||||
/>
|
||||
<path
|
||||
clipRule={'evenodd'}
|
||||
d={'M34.99 6.53a1.96 1.96 0 1 1 0 3.93 1.96 1.96 0 0 1 0-3.93z'}
|
||||
fill={'#FF0808'}
|
||||
fillRule={'evenodd'}
|
||||
/>
|
||||
<path
|
||||
clipRule={'evenodd'}
|
||||
d={
|
||||
'M19.5 16.04A2 2 0 0 1 21.5 18a2 2 0 0 1-2 1.96A2 2 0 0 1 17.46 18a2 2 0 0 1 2.02-1.96zM42.48 34.5a16.5 16.5 0 1 0 0-33 16.5 16.5 0 0 0 0 33zm0 1.5a18 18 0 1 0 0-36 18 18 0 0 0 0 36z'
|
||||
}
|
||||
fill={'#fff'}
|
||||
fillRule={'evenodd'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponent
|
||||
|
||||
@@ -1,31 +1,21 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath="url(#clip0_6627_107)">
|
||||
<path
|
||||
d="M4.66663 3.99996C4.84344 3.99996 5.01301 3.92972 5.13803 3.8047C5.26305 3.67967 5.33329 3.5101 5.33329 3.33329C5.33329 3.15648 5.26305 2.98691 5.13803 2.86189C5.01301 2.73686 4.84344 2.66663 4.66663 2.66663H3.33329C3.15648 2.66663 2.98691 2.73686 2.86189 2.86189C2.73686 2.98691 2.66663 3.15648 2.66663 3.33329V12.6666C2.66663 12.8434 2.73686 13.013 2.86189 13.138C2.98691 13.2631 3.15648 13.3333 3.33329 13.3333H4.66663C4.84344 13.3333 5.01301 13.2631 5.13803 13.138C5.26305 13.013 5.33329 12.8434 5.33329 12.6666C5.33329 12.4898 5.26305 12.3202 5.13803 12.1952C5.01301 12.0702 4.84344 12 4.66663 12H3.99996V3.99996H4.66663Z"
|
||||
fill="white"
|
||||
/>
|
||||
<path
|
||||
d="M13.88 7.61338L12 4.94672C11.898 4.80299 11.7433 4.70548 11.5697 4.67549C11.396 4.64551 11.2176 4.6855 11.0733 4.78672C11.0012 4.83724 10.9399 4.90154 10.8927 4.97592C10.8456 5.05029 10.8137 5.13326 10.7988 5.22004C10.784 5.30681 10.7864 5.39568 10.8061 5.4815C10.8257 5.56732 10.8622 5.64839 10.9133 5.72005L12.06 7.33338H6.66667C6.48986 7.33338 6.32029 7.40362 6.19526 7.52864C6.07024 7.65367 6 7.82324 6 8.00005C6 8.17686 6.07024 8.34643 6.19526 8.47145C6.32029 8.59648 6.48986 8.66672 6.66667 8.66672H12L10.8 10.2667C10.7475 10.3368 10.7093 10.4165 10.6875 10.5013C10.6658 10.5861 10.661 10.6743 10.6734 10.761C10.6857 10.8477 10.7151 10.931 10.7597 11.0064C10.8043 11.0817 10.8633 11.1475 10.9333 11.2C11.0487 11.2866 11.1891 11.3334 11.3333 11.3334C11.4368 11.3334 11.5389 11.3093 11.6315 11.263C11.724 11.2167 11.8046 11.1495 11.8667 11.0667L13.8667 8.40005C13.952 8.28729 13.9994 8.15031 14.0018 8.00889C14.0041 7.86748 13.9615 7.72897 13.88 7.61338Z"
|
||||
fill="white"
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_6627_107">
|
||||
<rect width="16" height="16" fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
import { SVGProps, Ref, forwardRef, memo } from "react"
|
||||
const SvgComponent = (
|
||||
props: SVGProps<SVGSVGElement>,
|
||||
ref: Ref<SVGSVGElement>
|
||||
) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={24}
|
||||
height={24}
|
||||
fill="none"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<g fill="#000" clipPath="url(#a)">
|
||||
<path d="M7 6a1 1 0 0 0 0-2H5a1 1 0 0 0-1 1v14a1 1 0 0 0 1 1h2a1 1 0 0 0 0-2H6V6h1Zm13.82 5.42-2.82-4a1 1 0 1 0-1.63 1.16L18.09 11H10a1 1 0 0 0 0 2h8l-1.8 2.4a1 1 0 0 0 1.6 1.2l3-4a1 1 0 0 0 .02-1.18Z" />
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
export default memo(ForwardRef)
|
||||
const Memo = memo(ForwardRef)
|
||||
export default Memo
|
||||
|
||||
@@ -1,22 +1,26 @@
|
||||
import { SVGProps } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={16}
|
||||
height={16}
|
||||
fill="none"
|
||||
viewBox="0 0 16 16"
|
||||
{...props}
|
||||
>
|
||||
<g fill="#fff" clipPath="url(#clip0_6693_1154)">
|
||||
<path d="M8 7.334a2.667 2.667 0 1 0 0-5.333 2.667 2.667 0 0 0 0 5.334zm0-4a1.333 1.333 0 1 1 0 2.667 1.333 1.333 0 0 1 0-2.666zM8 8.668a4.667 4.667 0 0 0-4.667 4.666.667.667 0 1 0 1.334 0 3.333 3.333 0 0 1 6.666 0 .667.667 0 1 0 1.334 0A4.667 4.667 0 0 0 8 8.668z" />
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_6693_1154">
|
||||
<path fill="#fff" d="M0 0h16v16H0z" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={16}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={16}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_6693_1154)'} fill={'#fff'}>
|
||||
<path
|
||||
d={
|
||||
'M8 7.334a2.667 2.667 0 1 0 0-5.333 2.667 2.667 0 0 0 0 5.334zm0-4a1.333 1.333 0 1 1 0 2.667 1.333 1.333 0 0 1 0-2.666zM8 8.668a4.667 4.667 0 0 0-4.667 4.666.667.667 0 1 0 1.334 0 3.333 3.333 0 0 1 6.666 0 .667.667 0 1 0 1.334 0A4.667 4.667 0 0 0 8 8.668z'
|
||||
}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_6693_1154'}>
|
||||
<path d={'M0 0h16v16H0z'} fill={'#fff'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponent
|
||||
|
||||
33
src/assets/icons/play-circle-outline.tsx
Normal file
33
src/assets/icons/play-circle-outline.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { SVGProps } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_28366_3435)'}>
|
||||
<path
|
||||
d={
|
||||
'M8.00004 1.33337C6.6815 1.33337 5.39257 1.72437 4.29624 2.45691C3.19991 3.18945 2.34543 4.23064 1.84085 5.44882C1.33626 6.66699 1.20424 8.00744 1.46148 9.30064C1.71871 10.5938 2.35365 11.7817 3.286 12.7141C4.21835 13.6464 5.40624 14.2814 6.69944 14.5386C7.99265 14.7958 9.33309 14.6638 10.5513 14.1592C11.7694 13.6547 12.8106 12.8002 13.5432 11.7038C14.2757 10.6075 14.6667 9.31858 14.6667 8.00004C14.6667 7.12456 14.4943 6.25766 14.1592 5.44882C13.8242 4.63998 13.3331 3.90505 12.7141 3.286C12.095 2.66694 11.3601 2.17588 10.5513 1.84084C9.74243 1.50581 8.87552 1.33337 8.00004 1.33337ZM8.00004 13.3334C6.94521 13.3334 5.91406 13.0206 5.037 12.4345C4.15994 11.8485 3.47635 11.0156 3.07269 10.041C2.66902 9.06648 2.5634 7.99412 2.76919 6.95956C2.97498 5.92499 3.48293 4.97468 4.22881 4.2288C4.97469 3.48292 5.925 2.97497 6.95956 2.76919C7.99413 2.5634 9.06648 2.66902 10.041 3.07268C11.0156 3.47635 11.8485 4.15994 12.4345 5.037C13.0206 5.91406 13.3334 6.94521 13.3334 8.00004C13.3334 9.41453 12.7715 10.7711 11.7713 11.7713C10.7711 12.7715 9.41453 13.3334 8.00004 13.3334Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
<path
|
||||
d={
|
||||
'M8.22666 4.96667C8.06331 4.81613 7.85932 4.71692 7.64004 4.68136C7.42077 4.6458 7.19588 4.67547 6.99333 4.76667C6.7967 4.84621 6.62825 4.98257 6.5095 5.15832C6.39075 5.33407 6.32709 5.54123 6.32666 5.75334V10.2467C6.32709 10.4588 6.39075 10.6659 6.5095 10.8417C6.62825 11.0174 6.7967 11.1538 6.99333 11.2333C7.13784 11.2989 7.29464 11.333 7.45333 11.3333C7.73927 11.3321 8.01467 11.2252 8.22666 11.0333L10.6667 8.78667C10.7758 8.68674 10.8629 8.56519 10.9226 8.42976C10.9822 8.29433 11.013 8.14798 11.013 8C11.013 7.85203 10.9822 7.70568 10.9226 7.57025C10.8629 7.43482 10.7758 7.31327 10.6667 7.21334L8.22666 4.96667ZM7.66666 9.73334V6.26667L9.53999 8L7.66666 9.73334Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_28366_3435'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponent
|
||||
28
src/assets/icons/search.tsx
Normal file
28
src/assets/icons/search.tsx
Normal file
@@ -0,0 +1,28 @@
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={20}
|
||||
ref={ref}
|
||||
viewBox={'0 0 20 20'}
|
||||
width={20}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_21547_180)'}>
|
||||
<path
|
||||
d={
|
||||
'M17.2583 16.075L14.425 13.25C15.3392 12.0854 15.8352 10.6472 15.8333 9.16667C15.8333 7.84813 15.4423 6.5592 14.7098 5.46287C13.9773 4.36654 12.9361 3.51206 11.7179 3.00747C10.4997 2.50289 9.15927 2.37087 7.86607 2.6281C6.57286 2.88534 5.38497 3.52027 4.45262 4.45262C3.52027 5.38497 2.88534 6.57286 2.6281 7.86607C2.37087 9.15927 2.50289 10.4997 3.00747 11.7179C3.51206 12.9361 4.36654 13.9773 5.46287 14.7098C6.5592 15.4423 7.84813 15.8333 9.16667 15.8333C10.6472 15.8352 12.0854 15.3392 13.25 14.425L16.075 17.2583C16.1525 17.3364 16.2446 17.3984 16.3462 17.4407C16.4477 17.4831 16.5567 17.5048 16.6667 17.5048C16.7767 17.5048 16.8856 17.4831 16.9871 17.4407C17.0887 17.3984 17.1809 17.3364 17.2583 17.2583C17.3364 17.1809 17.3984 17.0887 17.4407 16.9871C17.4831 16.8856 17.5048 16.7767 17.5048 16.6667C17.5048 16.5567 17.4831 16.4477 17.4407 16.3462C17.3984 16.2446 17.3364 16.1525 17.2583 16.075ZM4.16667 9.16667C4.16667 8.17776 4.45991 7.21106 5.00932 6.38882C5.55873 5.56657 6.33962 4.92571 7.25325 4.54727C8.16688 4.16883 9.17222 4.06982 10.1421 4.26274C11.112 4.45567 12.0029 4.93187 12.7022 5.63114C13.4015 6.3304 13.8777 7.22131 14.0706 8.19122C14.2635 9.16112 14.1645 10.1665 13.7861 11.0801C13.4076 11.9937 12.7668 12.7746 11.9445 13.324C11.1223 13.8734 10.1556 14.1667 9.16667 14.1667C7.84059 14.1667 6.56882 13.6399 5.63114 12.7022C4.69345 11.7645 4.16667 10.4928 4.16667 9.16667Z'
|
||||
}
|
||||
fill={'#808080'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_21547_180'}>
|
||||
<rect fill={'white'} height={20} width={20} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default memo(forwardRef(SvgComponent))
|
||||
27
src/assets/icons/trash-outline.tsx
Normal file
27
src/assets/icons/trash-outline.tsx
Normal file
@@ -0,0 +1,27 @@
|
||||
import { SVGProps } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>) => (
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={'16'}
|
||||
viewBox={'0 0 16 16'}
|
||||
width={'16'}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<g clipPath={'url(#clip0_28366_3245)'}>
|
||||
<path
|
||||
d={
|
||||
'M14 3.99998H10.6667V2.88665C10.6511 2.45986 10.4668 2.05669 10.1544 1.76551C9.842 1.47433 9.42687 1.31891 9.00004 1.33332H7.00004C6.57321 1.31891 6.15808 1.47433 5.84566 1.76551C5.53324 2.05669 5.34901 2.45986 5.33337 2.88665V3.99998H2.00004C1.82323 3.99998 1.65366 4.07022 1.52864 4.19525C1.40361 4.32027 1.33337 4.48984 1.33337 4.66665C1.33337 4.84346 1.40361 5.01303 1.52864 5.13805C1.65366 5.26308 1.82323 5.33332 2.00004 5.33332H2.66671V12.6666C2.66671 13.1971 2.87742 13.7058 3.25249 14.0809C3.62757 14.4559 4.13627 14.6666 4.66671 14.6666H11.3334C11.8638 14.6666 12.3725 14.4559 12.7476 14.0809C13.1227 13.7058 13.3334 13.1971 13.3334 12.6666V5.33332H14C14.1769 5.33332 14.3464 5.26308 14.4714 5.13805C14.5965 5.01303 14.6667 4.84346 14.6667 4.66665C14.6667 4.48984 14.5965 4.32027 14.4714 4.19525C14.3464 4.07022 14.1769 3.99998 14 3.99998ZM6.66671 2.88665C6.66671 2.77998 6.80671 2.66665 7.00004 2.66665H9.00004C9.19337 2.66665 9.33337 2.77998 9.33337 2.88665V3.99998H6.66671V2.88665ZM12 12.6666C12 12.8435 11.9298 13.013 11.8048 13.1381C11.6798 13.2631 11.5102 13.3333 11.3334 13.3333H4.66671C4.4899 13.3333 4.32033 13.2631 4.1953 13.1381C4.07028 13.013 4.00004 12.8435 4.00004 12.6666V5.33332H12V12.6666Z'
|
||||
}
|
||||
fill={'white'}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id={'clip0_28366_3245'}>
|
||||
<rect fill={'white'} height={'16'} width={'16'} />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
)
|
||||
|
||||
export default SvgComponent
|
||||
@@ -1,19 +1,21 @@
|
||||
import { SVGProps, Ref, forwardRef, memo } from 'react'
|
||||
import { Ref, SVGProps, forwardRef, memo } from 'react'
|
||||
const SvgComponent = (props: SVGProps<SVGSVGElement>, ref: Ref<SVGSVGElement>) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={20}
|
||||
height={20}
|
||||
fill="none"
|
||||
viewBox="0 0 24 24"
|
||||
ref={ref}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
fill="#fff"
|
||||
d="M12 5.975a9.77 9.77 0 0 1 8.82 5.5 9.647 9.647 0 0 1-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53-1.73-4.39-6-7.5-11-7.5-1.27 0-2.49.2-3.64.57l1.65 1.65c.65-.13 1.31-.22 1.99-.22zm-1.07 1.14L13 9.185c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07.01-2.48-2.01-4.49-4.49-4.49-.37 0-.72.05-1.07.14zm-8.92-3.27l2.68 2.68A11.738 11.738 0 0 0 1 11.475c1.73 4.39 6 7.5 11 7.5 1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.425l-1.41 1.42zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02a2.5 2.5 0 0 1-2.5-2.5c0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75a4.6 4.6 0 0 0-.36 1.78 4.507 4.507 0 0 0 6.27 4.14l.98.98c-.88.24-1.8.38-2.75.38a9.77 9.77 0 0 1-8.82-5.5c.7-1.43 1.72-2.61 2.93-3.53z"
|
||||
/>
|
||||
</svg>
|
||||
<svg
|
||||
fill={'none'}
|
||||
height={20}
|
||||
ref={ref}
|
||||
viewBox={'0 0 24 24'}
|
||||
width={20}
|
||||
xmlns={'http://www.w3.org/2000/svg'}
|
||||
{...props}
|
||||
>
|
||||
<path
|
||||
d={
|
||||
'M12 5.975a9.77 9.77 0 0 1 8.82 5.5 9.647 9.647 0 0 1-2.41 3.12l1.41 1.41c1.39-1.23 2.49-2.77 3.18-4.53-1.73-4.39-6-7.5-11-7.5-1.27 0-2.49.2-3.64.57l1.65 1.65c.65-.13 1.31-.22 1.99-.22zm-1.07 1.14L13 9.185c.57.25 1.03.71 1.28 1.28l2.07 2.07c.08-.34.14-.7.14-1.07.01-2.48-2.01-4.49-4.49-4.49-.37 0-.72.05-1.07.14zm-8.92-3.27l2.68 2.68A11.738 11.738 0 0 0 1 11.475c1.73 4.39 6 7.5 11 7.5 1.52 0 2.98-.29 4.32-.82l3.42 3.42 1.41-1.41L3.42 2.425l-1.41 1.42zm7.5 7.5l2.61 2.61c-.04.01-.08.02-.12.02a2.5 2.5 0 0 1-2.5-2.5c0-.05.01-.08.01-.13zm-3.4-3.4l1.75 1.75a4.6 4.6 0 0 0-.36 1.78 4.507 4.507 0 0 0 6.27 4.14l.98.98c-.88.24-1.8.38-2.75.38a9.77 9.77 0 0 1-8.82-5.5c.7-1.43 1.72-2.61 2.93-3.53z'
|
||||
}
|
||||
fill={'#fff'}
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
const ForwardRef = forwardRef(SvgComponent)
|
||||
|
||||
|
||||
13
src/components/ui/header/header.module.scss
Normal file
13
src/components/ui/header/header.module.scss
Normal file
@@ -0,0 +1,13 @@
|
||||
.header {
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
height: var(--header-height);
|
||||
padding: 12px 24px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid var(--Dark-500, #333);
|
||||
background: var(--Dark-700, #171717);
|
||||
}
|
||||
33
src/components/ui/header/header.stories.tsx
Normal file
33
src/components/ui/header/header.stories.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react'
|
||||
|
||||
import { Header } from './index.ts'
|
||||
|
||||
import { BrowserRouterDecorator } from '@/app/providers'
|
||||
|
||||
const meta = {
|
||||
title: 'Components/Header',
|
||||
component: Header,
|
||||
tags: ['autodocs'],
|
||||
decorators: [BrowserRouterDecorator],
|
||||
} satisfies Meta<typeof Header>
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const AuthorizedUser: Story = {
|
||||
args: {
|
||||
data: {
|
||||
name: 'User name',
|
||||
email: 'user-email.gmail.com',
|
||||
avatar: '',
|
||||
},
|
||||
logout: () => {},
|
||||
},
|
||||
}
|
||||
|
||||
export const UnauthorizedUser: Story = {
|
||||
args: {
|
||||
data: null,
|
||||
logout: () => {},
|
||||
},
|
||||
}
|
||||
4
src/components/ui/header/header.tsx
Normal file
4
src/components/ui/header/header.tsx
Normal file
@@ -0,0 +1,4 @@
|
||||
import s from './header.module.scss'
|
||||
export const Header = () => {
|
||||
return <header className={s.header}>Hello</header>
|
||||
}
|
||||
1
src/components/ui/header/index.ts
Normal file
1
src/components/ui/header/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { Header } from './header.tsx'
|
||||
10
src/components/ui/layout/layout.module.scss
Normal file
10
src/components/ui/layout/layout.module.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
.layout {
|
||||
}
|
||||
.main {
|
||||
padding-top: var(--header-height);
|
||||
padding-inline: 24px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
}
|
||||
21
src/components/ui/layout/layout.tsx
Normal file
21
src/components/ui/layout/layout.tsx
Normal file
@@ -0,0 +1,21 @@
|
||||
import { ComponentPropsWithoutRef, CSSProperties, ElementRef, forwardRef } from 'react'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import s from './layout.module.scss'
|
||||
|
||||
import { Header } from '@/components/ui/header'
|
||||
|
||||
type Props = ComponentPropsWithoutRef<'div'> & {
|
||||
contentMarginTop?: CSSProperties['marginTop']
|
||||
}
|
||||
export const Layout = forwardRef<ElementRef<'div'>, Props>(
|
||||
({ className, children, ...rest }, ref) => {
|
||||
return (
|
||||
<div ref={ref} {...rest}>
|
||||
<Header />
|
||||
<main className={s.main}>{children}</main>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)
|
||||
6
src/components/ui/page/page.module.scss
Normal file
6
src/components/ui/page/page.module.scss
Normal file
@@ -0,0 +1,6 @@
|
||||
.container {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
14
src/components/ui/page/page.tsx
Normal file
14
src/components/ui/page/page.tsx
Normal file
@@ -0,0 +1,14 @@
|
||||
import { ComponentPropsWithoutRef, CSSProperties } from 'react'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import s from './page.module.scss'
|
||||
type Props = ComponentPropsWithoutRef<'div'> & {
|
||||
mt?: CSSProperties['marginTop']
|
||||
}
|
||||
export const Page = ({ className, style, mt = '33px', ...rest }: Props) => {
|
||||
const classes = clsx(className, s.container)
|
||||
const styles: CSSProperties = { marginTop: mt, ...style }
|
||||
|
||||
return <div className={classes} style={styles} {...rest} />
|
||||
}
|
||||
1
src/components/ui/pagination/index.ts
Normal file
1
src/components/ui/pagination/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export * from './pagination'
|
||||
75
src/components/ui/pagination/pagination.module.scss
Normal file
75
src/components/ui/pagination/pagination.module.scss
Normal file
@@ -0,0 +1,75 @@
|
||||
.root {
|
||||
display: flex;
|
||||
gap: 25px;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
list-style-type: none;
|
||||
}
|
||||
|
||||
@mixin item {
|
||||
all: unset;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
color: var(--color-light-100);
|
||||
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.item {
|
||||
@include item;
|
||||
|
||||
cursor: pointer;
|
||||
|
||||
&:focus-visible {
|
||||
outline: var(--outline-focus);
|
||||
}
|
||||
|
||||
&:disabled {
|
||||
cursor: initial;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
&:hover:not(&:disabled) {
|
||||
background-color: var(--color-dark-500);
|
||||
}
|
||||
|
||||
&.selected {
|
||||
color: var(--color-dark-900);
|
||||
background-color: var(--color-light-100);
|
||||
}
|
||||
}
|
||||
|
||||
.dots {
|
||||
@include item;
|
||||
}
|
||||
|
||||
.icon {
|
||||
.item:disabled & {
|
||||
// important because icons have style prop
|
||||
color: var(--color-action-disabled) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.selectBox {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
align-items: center;
|
||||
|
||||
color: var(--color-light-100);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.select {
|
||||
flex-shrink: 0;
|
||||
width: 50px;
|
||||
}
|
||||
194
src/components/ui/pagination/pagination.tsx
Normal file
194
src/components/ui/pagination/pagination.tsx
Normal file
@@ -0,0 +1,194 @@
|
||||
import { FC } from 'react'
|
||||
|
||||
import { clsx } from 'clsx'
|
||||
|
||||
import s from './pagination.module.scss'
|
||||
import { usePagination } from './usePagination'
|
||||
|
||||
import { KeyboardArrowLeft, KeyboardArrowRight } from '@/assets'
|
||||
|
||||
type PaginationConditionals =
|
||||
| {
|
||||
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
|
||||
} & 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,
|
||||
}
|
||||
|
||||
export const Pagination: FC<PaginationProps> = ({
|
||||
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
|
||||
|
||||
return (
|
||||
<div className={classNames.root}>
|
||||
<div className={classNames.container}>
|
||||
<PrevButton disabled={isFirstPage} onClick={handlePreviousPageClicked} />
|
||||
|
||||
<MainPaginationButtons
|
||||
currentPage={page}
|
||||
onClick={handleMainPageClicked}
|
||||
paginationRange={paginationRange}
|
||||
/>
|
||||
|
||||
<NextButton disabled={isLastPage} onClick={handleNextPageClicked} />
|
||||
</div>
|
||||
|
||||
{showPerPageSelect && (
|
||||
<PerPageSelect
|
||||
{...{
|
||||
onPerPageChange,
|
||||
perPage,
|
||||
perPageOptions,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
type NavigationButtonProps = {
|
||||
disabled?: boolean
|
||||
onClick: () => void
|
||||
}
|
||||
|
||||
type PageButtonProps = NavigationButtonProps & {
|
||||
page: number
|
||||
selected: boolean
|
||||
}
|
||||
|
||||
const Dots: FC = () => {
|
||||
return <span className={classNames.dots}>…</span>
|
||||
}
|
||||
const PageButton: FC<PageButtonProps> = ({ disabled, onClick, page, selected }) => {
|
||||
return (
|
||||
<button
|
||||
className={classNames.pageButton(selected)}
|
||||
disabled={selected || disabled}
|
||||
onClick={onClick}
|
||||
>
|
||||
{page}
|
||||
</button>
|
||||
)
|
||||
}
|
||||
const PrevButton: FC<NavigationButtonProps> = ({ disabled, onClick }) => {
|
||||
return (
|
||||
<button className={classNames.item} disabled={disabled} onClick={onClick}>
|
||||
<KeyboardArrowLeft className={classNames.icon} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
const NextButton: FC<NavigationButtonProps> = ({ disabled, onClick }) => {
|
||||
return (
|
||||
<button className={classNames.item} disabled={disabled} onClick={onClick}>
|
||||
<KeyboardArrowRight className={classNames.icon} />
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
type MainPaginationButtonsProps = {
|
||||
currentPage: number
|
||||
onClick: (pageNumber: number) => () => void
|
||||
paginationRange: (number | string)[]
|
||||
}
|
||||
|
||||
const MainPaginationButtons: FC<MainPaginationButtonsProps> = ({
|
||||
currentPage,
|
||||
onClick,
|
||||
paginationRange,
|
||||
}) => {
|
||||
return (
|
||||
<>
|
||||
{paginationRange.map((page: number | string, index) => {
|
||||
const isSelected = page === currentPage
|
||||
|
||||
if (typeof page !== 'number') {
|
||||
return <Dots key={index} />
|
||||
}
|
||||
|
||||
return <PageButton key={index} onClick={onClick(page)} page={page} selected={isSelected} />
|
||||
})}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export type PerPageSelectProps = {
|
||||
onPerPageChange: (itemPerPage: number) => void
|
||||
perPage: number
|
||||
perPageOptions: number[]
|
||||
}
|
||||
|
||||
export const PerPageSelect: FC<PerPageSelectProps> = (
|
||||
{
|
||||
// perPage,
|
||||
// perPageOptions,
|
||||
// onPerPageChange,
|
||||
}
|
||||
) => {
|
||||
// const selectOptions = perPageOptions.map(value => ({
|
||||
// label: value,
|
||||
// value,
|
||||
// }))
|
||||
|
||||
return (
|
||||
<div className={classNames.selectBox}>
|
||||
Показать
|
||||
{/*<Select*/}
|
||||
{/* className={classNames.select}*/}
|
||||
{/* value={perPage}*/}
|
||||
{/* options={selectOptions}*/}
|
||||
{/* onChange={onPerPageChange}*/}
|
||||
{/* variant="pagination"*/}
|
||||
{/*/>*/}
|
||||
на странице
|
||||
</div>
|
||||
)
|
||||
}
|
||||
112
src/components/ui/pagination/usePagination.ts
Normal file
112
src/components/ui/pagination/usePagination.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
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
|
||||
|
||||
/*
|
||||
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)
|
||||
}
|
||||
|
||||
const DOTS = '...'
|
||||
|
||||
type UsePaginationParamType = {
|
||||
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
|
||||
|
||||
/*
|
||||
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)
|
||||
}
|
||||
|
||||
/*
|
||||
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)
|
||||
|
||||
/*
|
||||
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 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)
|
||||
|
||||
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)
|
||||
|
||||
return [firstPageIndex, DOTS, ...rightRange]
|
||||
}
|
||||
|
||||
/*
|
||||
Case 4: Both left and right dots to be shown
|
||||
*/
|
||||
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 {
|
||||
handleMainPageClicked,
|
||||
handleNextPageClicked,
|
||||
handlePreviousPageClicked,
|
||||
isFirstPage,
|
||||
isLastPage,
|
||||
paginationRange,
|
||||
}
|
||||
}
|
||||
10
src/pages/auth/login/login.tsx
Normal file
10
src/pages/auth/login/login.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
import { SignIn } from '@/components'
|
||||
import { Page } from '@/components/ui/page/page.tsx'
|
||||
|
||||
export const LoginPage = () => {
|
||||
return (
|
||||
<Page>
|
||||
<SignIn onSubmit={() => {}} />
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
25
src/pages/decks/decks.module.scss
Normal file
25
src/pages/decks/decks.module.scss
Normal file
@@ -0,0 +1,25 @@
|
||||
.header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.filter {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
margin-block: 36px;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
gap: 24px;
|
||||
|
||||
> * {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
101
src/pages/decks/decks.tsx
Normal file
101
src/pages/decks/decks.tsx
Normal file
@@ -0,0 +1,101 @@
|
||||
import { useSearchParams } from 'react-router-dom'
|
||||
|
||||
import s from './decks.module.scss'
|
||||
|
||||
import { Button, TextField, Typography } from '@/components'
|
||||
import { Page } from '@/components/ui/page/page.tsx'
|
||||
import { Pagination } from '@/components/ui/pagination'
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeadCell,
|
||||
TableRow,
|
||||
} from '@/components/ui/table'
|
||||
import { useCreateDeckMutation, useGetDecksQuery } from '@/services/decks/decks.service.ts'
|
||||
|
||||
export const Decks = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams({ page: '1', name: '' })
|
||||
const page = Number(searchParams.get('page'))
|
||||
const name = searchParams.get('name')
|
||||
const setPage = (page: number) => {
|
||||
searchParams.set('page', page.toString())
|
||||
setSearchParams(searchParams)
|
||||
}
|
||||
|
||||
const setName = (name: string) => {
|
||||
if (name === '') {
|
||||
searchParams.delete('name')
|
||||
} else {
|
||||
searchParams.set('name', name)
|
||||
}
|
||||
searchParams.set('page', '1')
|
||||
setSearchParams(searchParams)
|
||||
}
|
||||
const { data, isLoading, error } = useGetDecksQuery({
|
||||
currentPage: page || 1,
|
||||
itemsPerPage: 8,
|
||||
name: name ?? undefined,
|
||||
})
|
||||
|
||||
const [createDeck, { isLoading: isDeckBeingCreated }] = useCreateDeckMutation()
|
||||
|
||||
if (isLoading) {
|
||||
return <div>Loading...</div>
|
||||
}
|
||||
|
||||
if (error) {
|
||||
console.error(error)
|
||||
|
||||
return <div>Error</div>
|
||||
}
|
||||
|
||||
return (
|
||||
<Page>
|
||||
<div className={s.header}>
|
||||
<Typography variant="large" as={'h1'}>
|
||||
Decks
|
||||
</Typography>
|
||||
<Button onClick={() => createDeck({ name: '123123' })}>Add new deck</Button>
|
||||
</div>
|
||||
<div className={s.filter}>
|
||||
<TextField
|
||||
type={'search'}
|
||||
placeholder={'Search decks'}
|
||||
value={name ?? ''}
|
||||
onValueChange={setName}
|
||||
/>
|
||||
<div className={s.tabs}>
|
||||
<Button>My decks</Button>
|
||||
<Button>All decks</Button>
|
||||
</div>
|
||||
<input type={'range'} />
|
||||
<Button variant={'secondary'}>Clear</Button>
|
||||
</div>
|
||||
<Table width={'100%'}>
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableHeadCell>Name</TableHeadCell>
|
||||
<TableHeadCell>Cards</TableHeadCell>
|
||||
<TableHeadCell>Last updated</TableHeadCell>
|
||||
<TableHeadCell>Created by</TableHeadCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{data?.items.map(deck => {
|
||||
return (
|
||||
<TableRow key={deck.id}>
|
||||
<TableCell>{deck.name}</TableCell>
|
||||
<TableCell>{deck.cardsCount}</TableCell>
|
||||
<TableCell>{new Date(deck.updated).toLocaleDateString()}</TableCell>
|
||||
<TableCell>{deck.author.name}</TableCell>
|
||||
</TableRow>
|
||||
)
|
||||
})}
|
||||
</TableBody>
|
||||
</Table>
|
||||
<Pagination count={data?.pagination?.totalPages ?? 1} onChange={setPage} page={page} />
|
||||
</Page>
|
||||
)
|
||||
}
|
||||
35
src/router.tsx
Normal file
35
src/router.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
import { createBrowserRouter, Navigate, Outlet, RouterProvider } from 'react-router-dom'
|
||||
|
||||
import { LoginPage } from '@/pages/auth/login/login.tsx'
|
||||
import { Decks } from '@/pages/decks/decks.tsx'
|
||||
|
||||
const publicRoutes = [
|
||||
{
|
||||
path: '/login',
|
||||
element: <LoginPage />,
|
||||
},
|
||||
]
|
||||
const privateRoutes = [
|
||||
{
|
||||
path: '/',
|
||||
element: <Decks />,
|
||||
},
|
||||
]
|
||||
|
||||
const router = createBrowserRouter([
|
||||
...publicRoutes,
|
||||
{
|
||||
element: <PrivateRoutes />,
|
||||
children: privateRoutes,
|
||||
},
|
||||
])
|
||||
|
||||
export const Router = () => {
|
||||
return <RouterProvider router={router} />
|
||||
}
|
||||
|
||||
function PrivateRoutes() {
|
||||
const isAuthenticated = true
|
||||
|
||||
return isAuthenticated ? <Outlet /> : <Navigate to="/login" />
|
||||
}
|
||||
14
src/services/base-api.ts
Normal file
14
src/services/base-api.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { createApi, fetchBaseQuery } from '@reduxjs/toolkit/query/react'
|
||||
|
||||
export const baseApi = createApi({
|
||||
reducerPath: 'baseApi',
|
||||
tagTypes: ['Decks'],
|
||||
baseQuery: fetchBaseQuery({
|
||||
baseUrl: 'https://api.flashcards.andrii.es',
|
||||
credentials: 'include',
|
||||
prepareHeaders: headers => {
|
||||
headers.append('x-auth-skip', 'true')
|
||||
},
|
||||
}),
|
||||
endpoints: () => ({}),
|
||||
})
|
||||
40
src/services/decks/decks.service.ts
Normal file
40
src/services/decks/decks.service.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { baseApi } from '@/services/base-api.ts'
|
||||
import {
|
||||
CreateDeckArgs,
|
||||
Deck,
|
||||
GetDecksArgs,
|
||||
GetDecksResponse,
|
||||
} from '@/services/decks/decks.types.ts'
|
||||
|
||||
export const decksService = baseApi.injectEndpoints({
|
||||
endpoints: builder => {
|
||||
return {
|
||||
getDecks: builder.query<GetDecksResponse, GetDecksArgs | void>({
|
||||
query: params => {
|
||||
return {
|
||||
url: 'v1/decks',
|
||||
params: params ?? {},
|
||||
}
|
||||
},
|
||||
providesTags: ['Decks'],
|
||||
}),
|
||||
getDeckById: builder.query<Deck, { id: string }>({
|
||||
query: ({ id }) => {
|
||||
return {
|
||||
url: `v1/decks/${id}`,
|
||||
}
|
||||
},
|
||||
}),
|
||||
createDeck: builder.mutation<Deck, CreateDeckArgs>({
|
||||
query: args => ({
|
||||
url: 'v1/decks',
|
||||
method: 'POST',
|
||||
body: args,
|
||||
}),
|
||||
invalidatesTags: ['Decks'],
|
||||
}),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
export const { useGetDecksQuery, useGetDeckByIdQuery, useCreateDeckMutation } = decksService
|
||||
42
src/services/decks/decks.types.ts
Normal file
42
src/services/decks/decks.types.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
export type GetDecksResponse = {
|
||||
maxCardsCount: number
|
||||
pagination: Pagination
|
||||
items: Deck[]
|
||||
}
|
||||
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: null | string
|
||||
created: string
|
||||
updated: string
|
||||
cardsCount: number
|
||||
author: Author
|
||||
}
|
||||
|
||||
export type GetDecksArgs = {
|
||||
minCardsCount?: number
|
||||
maxCardsCount?: number
|
||||
name?: string
|
||||
authorId?: string
|
||||
orderBy?: string
|
||||
currentPage?: number
|
||||
itemsPerPage?: number
|
||||
}
|
||||
|
||||
export type CreateDeckArgs = {
|
||||
name: string
|
||||
isPrivate?: boolean
|
||||
}
|
||||
10
src/services/store.ts
Normal file
10
src/services/store.ts
Normal file
@@ -0,0 +1,10 @@
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
|
||||
import { baseApi } from '@/services/base-api.ts'
|
||||
|
||||
export const store = configureStore({
|
||||
reducer: { [baseApi.reducerPath]: baseApi.reducer },
|
||||
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(baseApi.middleware),
|
||||
})
|
||||
export type AppDispatch = typeof store.dispatch
|
||||
export type RootState = ReturnType<typeof store.getState>
|
||||
Reference in New Issue
Block a user