mirror of
https://git.vectorsigma.ru/public/photoview.git
synced 2026-08-03 21:59:12 +00:00
Work on settings page
This commit is contained in:
@@ -78,7 +78,9 @@ const LoginForm = () => {
|
||||
// loading={loading || (data && data.authorizeUser.success)}
|
||||
>
|
||||
<TextField
|
||||
className="w-full my-4"
|
||||
sizeVariant="big"
|
||||
wrapperClassName="my-4"
|
||||
className="w-full"
|
||||
label={t('login_page.field.username', 'Username')}
|
||||
{...register('username', { required: true })}
|
||||
error={
|
||||
@@ -88,7 +90,9 @@ const LoginForm = () => {
|
||||
}
|
||||
/>
|
||||
<TextField
|
||||
className="w-full my-4"
|
||||
sizeVariant="big"
|
||||
wrapperClassName="my-4"
|
||||
className="w-full"
|
||||
type="password"
|
||||
label={t('login_page.field.password', 'Password')}
|
||||
{...register('password', { required: true })}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import { gql } from '@apollo/client'
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { useMutation, useQuery } from '@apollo/client'
|
||||
import { Checkbox, Dropdown, Input, Loader } from 'semantic-ui-react'
|
||||
import { InputLabelDescription, InputLabelTitle } from './SettingsPage'
|
||||
import { Loader } from 'semantic-ui-react'
|
||||
import { InputLabelDescription } from './SettingsPage'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { scanIntervalQuery } from './__generated__/scanIntervalQuery'
|
||||
import {
|
||||
changeScanIntervalMutation,
|
||||
changeScanIntervalMutationVariables,
|
||||
} from './__generated__/changeScanIntervalMutation'
|
||||
import Checkbox from '../../primitives/form/Checkbox'
|
||||
import { TextField } from '../../primitives/form/Input'
|
||||
import Dropdown, { DropdownItem } from '../../primitives/form/Dropdown'
|
||||
|
||||
const SCAN_INTERVAL_QUERY = gql`
|
||||
query scanIntervalQuery {
|
||||
@@ -125,13 +128,11 @@ const PeriodicScanner = () => {
|
||||
},
|
||||
})
|
||||
|
||||
const [
|
||||
setScanIntervalMutation,
|
||||
{ loading: scanIntervalMutationLoading },
|
||||
] = useMutation<
|
||||
changeScanIntervalMutation,
|
||||
changeScanIntervalMutationVariables
|
||||
>(SCAN_INTERVAL_MUTATION)
|
||||
const [setScanIntervalMutation, { loading: scanIntervalMutationLoading }] =
|
||||
useMutation<
|
||||
changeScanIntervalMutation,
|
||||
changeScanIntervalMutationVariables
|
||||
>(SCAN_INTERVAL_MUTATION)
|
||||
|
||||
const onScanIntervalCheckboxChange = (checked: boolean) => {
|
||||
setEnablePeriodicScanner(checked)
|
||||
@@ -154,108 +155,83 @@ const PeriodicScanner = () => {
|
||||
}
|
||||
}
|
||||
|
||||
type scanIntervalUnitType = {
|
||||
key: TimeUnit
|
||||
text: string
|
||||
value: TimeUnit
|
||||
}
|
||||
|
||||
const scanIntervalUnits: scanIntervalUnitType[] = [
|
||||
const scanIntervalUnits: DropdownItem[] = [
|
||||
{
|
||||
key: TimeUnit.Second,
|
||||
text: t('settings.periodic_scanner.interval_unit.seconds', 'Seconds'),
|
||||
label: t('settings.periodic_scanner.interval_unit.seconds', 'Seconds'),
|
||||
value: TimeUnit.Second,
|
||||
},
|
||||
{
|
||||
key: TimeUnit.Minute,
|
||||
text: t('settings.periodic_scanner.interval_unit.minutes', 'Minutes'),
|
||||
label: t('settings.periodic_scanner.interval_unit.minutes', 'Minutes'),
|
||||
value: TimeUnit.Minute,
|
||||
},
|
||||
{
|
||||
key: TimeUnit.Hour,
|
||||
text: t('settings.periodic_scanner.interval_unit.hour', 'Hour'),
|
||||
label: t('settings.periodic_scanner.interval_unit.hour', 'Hour'),
|
||||
value: TimeUnit.Hour,
|
||||
},
|
||||
{
|
||||
key: TimeUnit.Day,
|
||||
text: t('settings.periodic_scanner.interval_unit.days', 'Days'),
|
||||
label: t('settings.periodic_scanner.interval_unit.days', 'Days'),
|
||||
value: TimeUnit.Day,
|
||||
},
|
||||
{
|
||||
key: TimeUnit.Month,
|
||||
text: t('settings.periodic_scanner.interval_unit.months', 'Months'),
|
||||
label: t('settings.periodic_scanner.interval_unit.months', 'Months'),
|
||||
value: TimeUnit.Month,
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<>
|
||||
<h3>{t('settings.periodic_scanner.title', 'Periodic scanner')}</h3>
|
||||
<h3 className="font-semibold text-lg mt-4 mb-2">
|
||||
{t('settings.periodic_scanner.title', 'Periodic scanner')}
|
||||
</h3>
|
||||
|
||||
<div style={{ margin: '12px 0' }}>
|
||||
<Checkbox
|
||||
label={t(
|
||||
'settings.periodic_scanner.checkbox_label',
|
||||
'Enable periodic scanner'
|
||||
)}
|
||||
disabled={scanIntervalQuery.loading}
|
||||
checked={enablePeriodicScanner}
|
||||
onChange={(_, { checked }) =>
|
||||
onScanIntervalCheckboxChange(checked || false)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<Checkbox
|
||||
label={t(
|
||||
'settings.periodic_scanner.checkbox_label',
|
||||
'Enable periodic scanner'
|
||||
)}
|
||||
disabled={scanIntervalQuery.loading}
|
||||
checked={enablePeriodicScanner}
|
||||
onChange={event =>
|
||||
onScanIntervalCheckboxChange(event.target.checked || false)
|
||||
}
|
||||
/>
|
||||
|
||||
{enablePeriodicScanner && (
|
||||
<>
|
||||
<label htmlFor="periodic_scan_field">
|
||||
<InputLabelTitle>
|
||||
{t(
|
||||
'settings.periodic_scanner.field.label',
|
||||
'Periodic scan interval'
|
||||
)}
|
||||
</InputLabelTitle>
|
||||
<InputLabelDescription>
|
||||
{t(
|
||||
'settings.periodic_scanner.field.description',
|
||||
'How often the scanner should perform automatic scans of all users'
|
||||
)}
|
||||
</InputLabelDescription>
|
||||
</label>
|
||||
<Input
|
||||
label={
|
||||
<Dropdown
|
||||
onChange={(_, { value }) => {
|
||||
const newScanInterval: TimeValue = {
|
||||
...scanInterval,
|
||||
unit: value as TimeUnit,
|
||||
}
|
||||
|
||||
setScanInterval(newScanInterval)
|
||||
onScanIntervalUpdate(newScanInterval)
|
||||
}}
|
||||
value={scanInterval.unit}
|
||||
options={scanIntervalUnits}
|
||||
/>
|
||||
}
|
||||
onBlur={() => onScanIntervalUpdate(scanInterval)}
|
||||
onKeyDown={({ key }: KeyboardEvent) =>
|
||||
key == 'Enter' && onScanIntervalUpdate(scanInterval)
|
||||
}
|
||||
loading={scanIntervalQuery.loading}
|
||||
labelPosition="right"
|
||||
style={{ maxWidth: 300 }}
|
||||
<div className="mt-4">
|
||||
<label htmlFor="periodic_scan_field">
|
||||
<h4 className="font-semibold">
|
||||
{t(
|
||||
'settings.periodic_scanner.field.label',
|
||||
'Periodic scan interval'
|
||||
)}
|
||||
</h4>
|
||||
<InputLabelDescription>
|
||||
{t(
|
||||
'settings.periodic_scanner.field.description',
|
||||
'How often the scanner should perform automatic scans of all users'
|
||||
)}
|
||||
</InputLabelDescription>
|
||||
</label>
|
||||
<div className="flex gap-2">
|
||||
<TextField
|
||||
id="periodic_scan_field"
|
||||
value={scanInterval.value}
|
||||
onChange={(_, { value }) => {
|
||||
setScanInterval(x => ({
|
||||
...x,
|
||||
value: parseInt(value),
|
||||
}))
|
||||
disabled={!enablePeriodicScanner}
|
||||
/>
|
||||
<Dropdown
|
||||
disabled={!enablePeriodicScanner}
|
||||
items={scanIntervalUnits}
|
||||
selected={scanInterval.unit}
|
||||
setSelected={value => {
|
||||
const newScanInterval: TimeValue = {
|
||||
...scanInterval,
|
||||
unit: value as TimeUnit,
|
||||
}
|
||||
|
||||
setScanInterval(newScanInterval)
|
||||
onScanIntervalUpdate(newScanInterval)
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<Loader
|
||||
active={scanIntervalQuery.loading || scanIntervalMutationLoading}
|
||||
inline
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useRef, useState } from 'react'
|
||||
import { useQuery, useMutation, gql } from '@apollo/client'
|
||||
import { Input, Loader } from 'semantic-ui-react'
|
||||
// import { Input, Loader } from 'semantic-ui-react'
|
||||
import { InputLabelTitle, InputLabelDescription } from './SettingsPage'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { concurrentWorkersQuery } from './__generated__/concurrentWorkersQuery'
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
setConcurrentWorkers,
|
||||
setConcurrentWorkersVariables,
|
||||
} from './__generated__/setConcurrentWorkers'
|
||||
import { TextField } from '../../primitives/form/Input'
|
||||
|
||||
const CONCURRENT_WORKERS_QUERY = gql`
|
||||
query concurrentWorkersQuery {
|
||||
@@ -56,7 +57,7 @@ const ScannerConcurrentWorkers = () => {
|
||||
}
|
||||
|
||||
return (
|
||||
<div style={{ marginTop: 32 }}>
|
||||
<div>
|
||||
<label htmlFor="scanner_concurrent_workers_field">
|
||||
<InputLabelTitle>
|
||||
{t('settings.concurrent_workers.title', 'Scanner concurrent workers')}
|
||||
@@ -68,27 +69,27 @@ const ScannerConcurrentWorkers = () => {
|
||||
)}
|
||||
</InputLabelDescription>
|
||||
</label>
|
||||
<Input
|
||||
<TextField
|
||||
disabled={workerAmountQuery.loading || workersMutationData.loading}
|
||||
type="number"
|
||||
min="1"
|
||||
max="24"
|
||||
id="scanner_concurrent_workers_field"
|
||||
value={workerAmount}
|
||||
onChange={(_, { value }) => {
|
||||
setWorkerAmount(parseInt(value))
|
||||
onChange={event => {
|
||||
setWorkerAmount(parseInt(event.target.value))
|
||||
}}
|
||||
onBlur={() => updateWorkerAmount(workerAmount)}
|
||||
onKeyDown={({ key }: KeyboardEvent) =>
|
||||
key == 'Enter' && updateWorkerAmount(workerAmount)
|
||||
onKeyDown={event =>
|
||||
event.key == 'Enter' && updateWorkerAmount(workerAmount)
|
||||
}
|
||||
/>
|
||||
<Loader
|
||||
{/* <Loader
|
||||
active={workerAmountQuery.loading || workersMutationData.loading}
|
||||
inline
|
||||
size="small"
|
||||
style={{ marginLeft: 16 }}
|
||||
/>
|
||||
/> */}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import React from 'react'
|
||||
import { useMutation, gql } from '@apollo/client'
|
||||
import { Button, Icon } from 'semantic-ui-react'
|
||||
import PeriodicScanner from './PeriodicScanner'
|
||||
import ScannerConcurrentWorkers from './ScannerConcurrentWorkers'
|
||||
import { SectionTitle, InputLabelDescription } from './SettingsPage'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { scanAllMutation } from './__generated__/scanAllMutation'
|
||||
import { Button } from '../../primitives/form/Input'
|
||||
|
||||
const SCAN_MUTATION = gql`
|
||||
mutation scanAllMutation {
|
||||
@@ -32,14 +32,12 @@ const ScannerSection = () => {
|
||||
)}
|
||||
</InputLabelDescription>
|
||||
<Button
|
||||
icon
|
||||
labelPosition="left"
|
||||
className="my-2"
|
||||
onClick={() => {
|
||||
startScanner()
|
||||
}}
|
||||
disabled={called}
|
||||
>
|
||||
<Icon name="sync" />
|
||||
{t('settings.scanner.scan_all_users', 'Scan all users')}
|
||||
</Button>
|
||||
<PeriodicScanner />
|
||||
|
||||
@@ -1,32 +1,39 @@
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Button } from 'semantic-ui-react'
|
||||
import styled from 'styled-components'
|
||||
import { useIsAdmin } from '../../components/routes/AuthorizedRoute'
|
||||
|
||||
import Layout from '../../components/layout/Layout'
|
||||
|
||||
import ScannerSection from './ScannerSection'
|
||||
import UserPreferences from './UserPreferences'
|
||||
import UsersTable from './Users/UsersTable'
|
||||
import VersionInfo from './VersionInfo'
|
||||
import classNames from 'classnames'
|
||||
|
||||
export const SectionTitle = styled.h2<{ nospace?: boolean }>`
|
||||
margin-top: ${({ nospace }) => (nospace ? '0' : '1.4em')} !important;
|
||||
padding-bottom: 0.3em;
|
||||
border-bottom: 1px solid #ddd;
|
||||
`
|
||||
type SectionTitleProps = {
|
||||
children: string
|
||||
nospace?: boolean
|
||||
}
|
||||
|
||||
export const InputLabelTitle = styled.p`
|
||||
font-size: 1.1em;
|
||||
font-weight: 600;
|
||||
margin: 1em 0 0 !important;
|
||||
`
|
||||
export const SectionTitle = ({ children, nospace }: SectionTitleProps) => {
|
||||
return (
|
||||
<h2
|
||||
className={classNames(
|
||||
'pb-1 border-b border-gray-200 text-xl mb-5',
|
||||
!nospace && 'mt-6'
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
)
|
||||
}
|
||||
|
||||
export const InputLabelDescription = styled.p`
|
||||
font-size: 0.9em;
|
||||
margin: 0 0 0.5em !important;
|
||||
`
|
||||
export const InputLabelTitle = styled.h3.attrs({
|
||||
className: 'font-semibold',
|
||||
})``
|
||||
|
||||
export const InputLabelDescription = styled.p.attrs({
|
||||
className: 'text-sm mb-2',
|
||||
})``
|
||||
|
||||
const SettingsPage = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -41,14 +48,6 @@ const SettingsPage = () => {
|
||||
<UsersTable />
|
||||
</>
|
||||
)}
|
||||
<Button
|
||||
style={{ marginTop: 24 }}
|
||||
onClick={() => {
|
||||
location.href = '/logout'
|
||||
}}
|
||||
>
|
||||
{t('settings.logout', 'Log out')}
|
||||
</Button>
|
||||
<VersionInfo />
|
||||
</Layout>
|
||||
)
|
||||
|
||||
@@ -2,9 +2,10 @@ import { useMutation, useQuery } from '@apollo/client'
|
||||
import gql from 'graphql-tag'
|
||||
import React, { useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Dropdown } from 'semantic-ui-react'
|
||||
import styled from 'styled-components'
|
||||
import { LanguageTranslation } from '../../../__generated__/globalTypes'
|
||||
import Dropdown from '../../primitives/form/Dropdown'
|
||||
import { Button } from '../../primitives/form/Input'
|
||||
import {
|
||||
InputLabelDescription,
|
||||
InputLabelTitle,
|
||||
@@ -17,14 +18,14 @@ import {
|
||||
import { myUserPreferences } from './__generated__/myUserPreferences'
|
||||
|
||||
const languagePreferences = [
|
||||
{ key: 1, text: 'English', flag: 'uk', value: LanguageTranslation.English },
|
||||
{ key: 2, text: 'Français', flag: 'fr', value: LanguageTranslation.French },
|
||||
{ key: 3, text: 'Svenska', flag: 'se', value: LanguageTranslation.Swedish },
|
||||
{ key: 4, text: 'Dansk', flag: 'dk', value: LanguageTranslation.Danish },
|
||||
{ key: 5, text: 'Español', flag: 'es', value: LanguageTranslation.Spanish },
|
||||
{ key: 6, text: 'polski', flag: 'pl', value: LanguageTranslation.Polish },
|
||||
{ key: 7, text: 'Italiano', flag: 'it', value: LanguageTranslation.Italian },
|
||||
{ key: 8, text: 'Deutsch', flag: 'de', value: LanguageTranslation.German },
|
||||
{ key: 1, label: 'English', flag: 'uk', value: LanguageTranslation.English },
|
||||
{ key: 2, label: 'Français', flag: 'fr', value: LanguageTranslation.French },
|
||||
{ key: 3, label: 'Svenska', flag: 'se', value: LanguageTranslation.Swedish },
|
||||
{ key: 4, label: 'Dansk', flag: 'dk', value: LanguageTranslation.Danish },
|
||||
{ key: 5, label: 'Español', flag: 'es', value: LanguageTranslation.Spanish },
|
||||
{ key: 6, label: 'polski', flag: 'pl', value: LanguageTranslation.Polish },
|
||||
{ key: 7, label: 'Italiano', flag: 'it', value: LanguageTranslation.Italian },
|
||||
{ key: 8, label: 'Deutsch', flag: 'de', value: LanguageTranslation.German },
|
||||
]
|
||||
|
||||
const CHANGE_USER_PREFERENCES = gql`
|
||||
@@ -45,6 +46,21 @@ const MY_USER_PREFERENCES = gql`
|
||||
}
|
||||
`
|
||||
|
||||
const LogoutButton = () => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<Button
|
||||
className="mb-4"
|
||||
onClick={() => {
|
||||
location.href = '/logout'
|
||||
}}
|
||||
>
|
||||
{t('settings.logout', 'Log out')}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
|
||||
const UserPreferencesWrapper = styled.div`
|
||||
margin-bottom: 24px;
|
||||
`
|
||||
@@ -60,7 +76,7 @@ const UserPreferences = () => {
|
||||
>(CHANGE_USER_PREFERENCES)
|
||||
|
||||
const sortedLanguagePrefs = useMemo(
|
||||
() => languagePreferences.sort((a, b) => a.text.localeCompare(b.text)),
|
||||
() => languagePreferences.sort((a, b) => a.label.localeCompare(b.label)),
|
||||
[]
|
||||
)
|
||||
|
||||
@@ -73,6 +89,7 @@ const UserPreferences = () => {
|
||||
<SectionTitle nospace>
|
||||
{t('settings.user_preferences.title', 'User preferences')}
|
||||
</SectionTitle>
|
||||
<LogoutButton />
|
||||
<label id="user_pref_change_language_field">
|
||||
<InputLabelTitle>
|
||||
{t(
|
||||
@@ -93,19 +110,18 @@ const UserPreferences = () => {
|
||||
'settings.user_preferences.language_selector.placeholder',
|
||||
'Select language'
|
||||
)}
|
||||
clearable
|
||||
options={sortedLanguagePrefs}
|
||||
onChange={(event, { value: language }) => {
|
||||
items={sortedLanguagePrefs}
|
||||
setSelected={language => {
|
||||
changePrefs({
|
||||
variables: {
|
||||
language: language as LanguageTranslation,
|
||||
},
|
||||
})
|
||||
}}
|
||||
selection
|
||||
search
|
||||
value={data?.myUserPreferences.language || undefined}
|
||||
loading={loadingPrefs}
|
||||
// selection
|
||||
// search
|
||||
selected={data?.myUserPreferences.language || undefined}
|
||||
// loading={loadingPrefs}
|
||||
disabled={loadingPrefs}
|
||||
/>
|
||||
</UserPreferencesWrapper>
|
||||
|
||||
@@ -202,7 +202,6 @@ const MorePopoverSectionPassword = ({
|
||||
disabled={!activated}
|
||||
type={passwordHidden ? 'password' : 'text'}
|
||||
value={passwordInputValue}
|
||||
sizeVariant="small"
|
||||
className="mt-2"
|
||||
onKeyDown={event => {
|
||||
if (
|
||||
@@ -252,7 +251,7 @@ const MorePopover = ({ id, share, query }: MorePopoverProps) => {
|
||||
<MorePopoverSectionPassword id={id} share={share} query={query} />
|
||||
<div className="px-4 py-2 border-t border-gray-200 mt-2 mb-2">
|
||||
<Checkbox label="Expiration date" />
|
||||
<TextField sizeVariant="small" className="mt-2" />
|
||||
<TextField className="mt-2" />
|
||||
</div>
|
||||
</ArrowPopoverPanel>
|
||||
</Popover.Panel>
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import classNames from 'classnames'
|
||||
import React from 'react'
|
||||
import styled from 'styled-components'
|
||||
|
||||
@@ -9,7 +10,7 @@ const DropdownStyledSelect = styled.select`
|
||||
background-position: center right 10px;
|
||||
`
|
||||
|
||||
type DropdownItem = {
|
||||
export type DropdownItem = {
|
||||
value: string
|
||||
label: string
|
||||
}
|
||||
@@ -17,13 +18,14 @@ type DropdownItem = {
|
||||
type DropdownProps = React.SelectHTMLAttributes<HTMLSelectElement> & {
|
||||
items: DropdownItem[]
|
||||
selected?: string
|
||||
setSelected(label: string): void
|
||||
setSelected(value: string): void
|
||||
}
|
||||
|
||||
const Dropdown = ({
|
||||
items,
|
||||
selected,
|
||||
setSelected,
|
||||
className,
|
||||
...otherProps
|
||||
}: DropdownProps) => {
|
||||
const onChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||
@@ -39,7 +41,10 @@ const Dropdown = ({
|
||||
|
||||
return (
|
||||
<DropdownStyledSelect
|
||||
className="bg-gray-50 px-2 py-0.5 pr-6 rounded border border-gray-200 focus:outline-none focus:border-blue-300 text-[#222] hover:bg-gray-100"
|
||||
className={classNames(
|
||||
'bg-gray-50 px-2 py-0.5 pr-6 rounded border border-gray-200 focus:outline-none focus:border-blue-300 text-[#222] hover:bg-gray-100 disabled:hover:bg-gray-50 disabled:text-gray-500 disabled:cursor-default',
|
||||
className
|
||||
)}
|
||||
value={selected}
|
||||
onChange={onChange}
|
||||
{...otherProps}
|
||||
|
||||
@@ -8,7 +8,8 @@ type TextFieldProps = {
|
||||
label?: string
|
||||
error?: string
|
||||
className?: ClassNamesArg
|
||||
sizeVariant?: 'default' | 'small'
|
||||
wrapperClassName?: ClassNamesArg
|
||||
sizeVariant?: 'default' | 'big'
|
||||
action?: () => void
|
||||
loading?: boolean
|
||||
} & Omit<React.InputHTMLAttributes<HTMLInputElement>, 'className'>
|
||||
@@ -19,6 +20,7 @@ export const TextField = forwardRef(
|
||||
label,
|
||||
error,
|
||||
className,
|
||||
wrapperClassName,
|
||||
sizeVariant,
|
||||
action,
|
||||
loading,
|
||||
@@ -52,9 +54,10 @@ export const TextField = forwardRef(
|
||||
<input
|
||||
onKeyUp={keyUpEvent}
|
||||
className={classNames(
|
||||
'block border rounded-md w-full focus:ring-2 focus:outline-none px-2',
|
||||
'block border rounded-md focus:ring-2 focus:outline-none px-2',
|
||||
variant,
|
||||
sizeVariant == 'default' ? 'py-2' : 'py-1'
|
||||
sizeVariant == 'big' ? 'py-2' : 'py-1',
|
||||
className
|
||||
)}
|
||||
{...inputProps}
|
||||
ref={ref}
|
||||
@@ -79,8 +82,7 @@ export const TextField = forwardRef(
|
||||
disabled={disabled}
|
||||
aria-label="Submit"
|
||||
className={classNames(
|
||||
'absolute top-[1px] right-0 p-2',
|
||||
disabled ? 'text-gray-400 cursor-default' : 'text-gray-600'
|
||||
'absolute top-[1px] right-0 p-2 text-gray-600 disabled:text-gray-400 disabled:cursor-default'
|
||||
)}
|
||||
onClick={() => action()}
|
||||
>
|
||||
@@ -94,8 +96,8 @@ export const TextField = forwardRef(
|
||||
if (error) errorElm = <div className="text-red-800">{error}</div>
|
||||
|
||||
const wrapperClasses = classNames(
|
||||
className,
|
||||
sizeVariant == 'small' && 'text-sm'
|
||||
sizeVariant == 'default' && 'text-sm',
|
||||
wrapperClassName
|
||||
)
|
||||
|
||||
if (label) {
|
||||
@@ -119,12 +121,26 @@ export const TextField = forwardRef(
|
||||
}
|
||||
)
|
||||
|
||||
export const Submit = (props: React.InputHTMLAttributes<HTMLInputElement>) => {
|
||||
return (
|
||||
<input
|
||||
className={`rounded-md px-8 py-2 focus:outline-none hover:cursor-pointer bg-[#eee] hover:bg-[#e6e6e6] focus:bg-[#e6e6e6] ${props.className}`}
|
||||
type="submit"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
}
|
||||
const buttonStyles =
|
||||
'bg-gray-50 px-6 py-0.5 rounded border border-gray-200 focus:outline-none focus:border-blue-300 text-[#222] hover:bg-gray-100'
|
||||
|
||||
export const Submit = ({
|
||||
className,
|
||||
...props
|
||||
}: React.InputHTMLAttributes<HTMLInputElement>) => (
|
||||
<input
|
||||
className={classNames(buttonStyles, className)}
|
||||
type="submit"
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
|
||||
export const Button = ({
|
||||
children,
|
||||
className,
|
||||
...props
|
||||
}: React.ButtonHTMLAttributes<HTMLButtonElement>) => (
|
||||
<button className={classNames(buttonStyles, className)} {...props}>
|
||||
{children}
|
||||
</button>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user