Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
F
frontend
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
vicotor
frontend
Commits
b8789b81
Commit
b8789b81
authored
Mar 05, 2025
by
tom
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
token info form
parent
62d5b8e4
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
169 additions
and
85 deletions
+169
-85
field.tsx
toolkit/chakra/field.tsx
+11
-4
field.recipe.ts
toolkit/theme/recipes/field.recipe.ts
+6
-0
VerifiedAddresses.tsx
ui/pages/VerifiedAddresses.tsx
+2
-3
ImageUrlPreview.tsx
ui/shared/forms/components/ImageUrlPreview.tsx
+6
-5
FormFieldFancySelect.tsx
ui/shared/forms/fields/FormFieldFancySelect.tsx
+1
-0
FormFieldSelect.tsx
ui/shared/forms/fields/FormFieldSelect.tsx
+65
-0
Field.tsx
ui/showcases/Field.tsx
+12
-12
TokenInfoForm.tsx
ui/tokenInfo/TokenInfoForm.tsx
+17
-21
TokenInfoFormSectionHeader.tsx
ui/tokenInfo/TokenInfoFormSectionHeader.tsx
+6
-2
TokenInfoFormStatusText.tsx
ui/tokenInfo/TokenInfoFormStatusText.tsx
+2
-1
TokenInfoIconPreview.tsx
ui/tokenInfo/TokenInfoIconPreview.tsx
+4
-4
TokenInfoFieldIconUrl.tsx
ui/tokenInfo/fields/TokenInfoFieldIconUrl.tsx
+7
-7
TokenInfoFieldProjectSector.tsx
ui/tokenInfo/fields/TokenInfoFieldProjectSector.tsx
+10
-8
TokenInfoFieldSocialLink.tsx
ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx
+14
-12
TokenInfoFieldSupport.tsx
ui/tokenInfo/fields/TokenInfoFieldSupport.tsx
+3
-3
types.ts
ui/tokenInfo/types.ts
+1
-1
utils.ts
ui/tokenInfo/utils.ts
+2
-2
No files found.
toolkit/chakra/field.tsx
View file @
b8789b81
...
...
@@ -20,12 +20,12 @@ export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
const
{
label
,
children
,
helperText
,
errorText
,
optionalText
,
...
rest
}
=
props
;
// A floating field cannot be without a label.
if
(
props
.
floating
&&
label
)
{
if
(
rest
.
floating
&&
label
)
{
const
injectedProps
=
{
className
:
'
peer
'
,
placeholder
:
'
'
,
size
:
props
.
size
,
floating
:
props
.
floating
,
size
:
rest
.
size
,
floating
:
rest
.
floating
,
bgColor
:
rest
.
bgColor
,
disabled
:
rest
.
disabled
,
readOnly
:
rest
.
readOnly
,
...
...
@@ -79,6 +79,13 @@ export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
);
}
// Pass size value to the input component
const
injectedProps
=
{
size
:
rest
.
size
,
};
const
child
=
React
.
Children
.
only
<
React
.
ReactElement
<
InputProps
|
InputGroupProps
>>
(
children
);
const
clonedChild
=
React
.
cloneElement
(
child
,
injectedProps
);
return
(
<
ChakraField
.
Root
ref=
{
ref
}
{
...
rest
}
>
{
label
&&
(
...
...
@@ -87,7 +94,7 @@ export const Field = React.forwardRef<HTMLDivElement, FieldProps>(
<
ChakraField
.
RequiredIndicator
fallback=
{
optionalText
}
/>
</
ChakraField
.
Label
>
)
}
{
c
hildren
}
{
c
lonedChild
}
{
helperText
&&
(
<
ChakraField
.
HelperText
>
{
helperText
}
</
ChakraField
.
HelperText
>
)
}
...
...
toolkit/theme/recipes/field.recipe.ts
View file @
b8789b81
...
...
@@ -117,6 +117,9 @@ export const recipe = defineSlotRecipe({
floating
:
true
,
css
:
{
label
:
{
whiteSpace
:
'
nowrap
'
,
overflow
:
'
hidden
'
,
textOverflow
:
'
ellipsis
'
,
padding
:
'
10px 16px 0px 16px
'
,
textStyle
:
'
xs
'
,
_peerPlaceholderShown
:
{
...
...
@@ -142,6 +145,9 @@ export const recipe = defineSlotRecipe({
floating
:
true
,
css
:
{
label
:
{
whiteSpace
:
'
nowrap
'
,
overflow
:
'
hidden
'
,
textOverflow
:
'
ellipsis
'
,
// 16px = scrollbar width
width
:
'
calc(100% - 4px - 20px)
'
,
padding
:
'
20px 24px 0px 24px
'
,
...
...
ui/pages/VerifiedAddresses.tsx
View file @
b8789b81
...
...
@@ -12,7 +12,6 @@ import getQueryParamString from 'lib/router/getQueryParamString';
import
{
TOKEN_INFO_APPLICATION
,
VERIFIED_ADDRESS
}
from
'
stubs/account
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
Link
}
from
'
toolkit/chakra/link
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
import
{
useDisclosure
}
from
'
toolkit/hooks/useDisclosure
'
;
import
AddressVerificationModal
from
'
ui/addressVerification/AddressVerificationModal
'
;
import
AccountPageDescription
from
'
ui/shared/AccountPageDescription
'
;
...
...
@@ -144,12 +143,12 @@ const VerifiedAddresses = () => {
return
(
<>
<
PageTitle
title=
"Token info application form"
backLink=
{
backLink
}
/>
{
/*
<TokenInfoForm
<
TokenInfoForm
address=
{
selectedAddress
}
tokenName=
{
tokenName
}
application=
{
applicationsQuery
.
data
?.
submissions
.
find
(({
tokenAddress
})
=>
tokenAddress
.
toLowerCase
()
===
selectedAddress
.
toLowerCase
())
}
onSubmit=
{
handleApplicationSubmit
}
/>
*/
}
/>
</>
);
}
...
...
ui/shared/forms/components/ImageUrlPreview.tsx
View file @
b8789b81
import
type
{
ColorMode
}
from
'
@chakra-ui/react
'
;
import
{
Image
,
chakra
,
DarkMode
}
from
'
@chakra-ui/react
'
;
import
{
chakra
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
Skeleton
from
'
ui/shared/chakra/Skeleton
'
;
import
type
{
ColorMode
}
from
'
toolkit/chakra/color-mode
'
;
import
{
Image
}
from
'
toolkit/chakra/image
'
;
import
{
Skeleton
}
from
'
toolkit/chakra/skeleton
'
;
interface
Props
{
src
:
string
|
undefined
;
...
...
@@ -23,11 +24,11 @@ const ImageUrlPreview = ({
fallback
:
fallbackProp
,
colorMode
,
}:
Props
)
=>
{
const
skeleton
=
<
Skeleton
className=
{
className
}
w=
"100%"
h=
"100%"
/>;
const
skeleton
=
<
Skeleton
loading
className=
{
[
className
,
colorMode
===
'
dark
'
?
'
dark
'
:
undefined
].
filter
(
Boolean
).
join
(
'
'
)
}
w=
"100%"
h=
"100%"
/>;
const
fallback
=
(()
=>
{
if
(
src
&&
!
isInvalid
)
{
return
colorMode
===
'
dark
'
?
<
DarkMode
>
{
skeleton
}
</
DarkMode
>
:
skeleton
;
return
skeleton
;
}
return
fallbackProp
;
})();
...
...
ui/shared/forms/fields/FormFieldFancySelect.tsx
View file @
b8789b81
...
...
@@ -13,6 +13,7 @@ import FancySelect from 'ui/shared/forms/inputs/select/FancySelect';
// this type only works for plain objects, not for nested objects or arrays (e.g. ui/publicTags/submit/types.ts:FormFields)
// type SelectField<O> = { [K in keyof O]: NonNullable<O[K]> extends Option ? K : never }[keyof O];
// TODO @tom2drum remove this component
type
Props
<
FormFields
extends
FieldValues
,
Name
extends
Path
<
FormFields
>
,
...
...
ui/shared/forms/fields/FormFieldSelect.tsx
0 → 100644
View file @
b8789b81
import
React
from
'
react
'
;
import
type
{
Path
,
FieldValues
}
from
'
react-hook-form
'
;
import
{
useController
,
useFormContext
}
from
'
react-hook-form
'
;
import
type
{
FormFieldPropsBase
}
from
'
./types
'
;
import
type
{
SelectRootProps
}
from
'
toolkit/chakra/select
'
;
import
{
SelectContent
,
SelectControl
,
SelectItem
,
SelectRoot
,
SelectValueText
}
from
'
toolkit/chakra/select
'
;
type
Props
<
FormFields
extends
FieldValues
,
Name
extends
Path
<
FormFields
>
,
>
=
FormFieldPropsBase
<
FormFields
,
Name
>
&
SelectRootProps
;
const
FormFieldSelect
=
<
FormFields
extends
FieldValues
,
Name
extends
Path
<
FormFields
>
,
>
(props: Props
<
FormFields
,
Name
>
) =
>
{
const
{
name
,
rules
,
collection
,
placeholder
,
...
rest
}
=
props
;
const
{
control
}
=
useFormContext
<
FormFields
>
();
const
{
field
,
fieldState
,
formState
}
=
useController
<
FormFields
,
typeof
name
>
({
control
,
name
,
rules
,
});
const
isDisabled
=
formState
.
isSubmitting
;
const
handleChange
=
React
.
useCallback
(({
value
}:
{
value
:
Array
<
string
>
})
=>
{
field
.
onChange
(
value
);
},
[
field
]);
const
handleBlur
=
React
.
useCallback
(()
=>
{
field
.
onBlur
();
},
[
field
]);
// TODO @tom2drum: fix initial value is not displayed in the select
return
(
<
SelectRoot
ref=
{
field
.
ref
}
name=
{
field
.
name
}
value=
{
field
.
value
}
onValueChange=
{
handleChange
}
onInteractOutside=
{
handleBlur
}
collection=
{
collection
}
disabled=
{
isDisabled
}
invalid=
{
Boolean
(
fieldState
.
error
)
}
{
...
rest
}
>
<
SelectControl
>
<
SelectValueText
placeholder=
{
placeholder
}
/>
</
SelectControl
>
<
SelectContent
>
{
collection
.
items
.
map
((
item
)
=>
(
<
SelectItem
item=
{
item
}
key=
{
item
.
value
}
>
{
item
.
label
}
</
SelectItem
>
))
}
</
SelectContent
>
</
SelectRoot
>
);
}
;
export default React.memo(FormFieldSelect) as typeof FormFieldSelect;
ui/showcases/Field.tsx
View file @
b8789b81
...
...
@@ -15,32 +15,32 @@ const FieldShowcase = () => {
{
([
'
sm
'
,
'
md
'
,
'
lg
'
]
as
const
).
map
((
size
)
=>
(
<
Sample
label=
{
`size: ${ size }`
}
w=
"100%"
key=
{
size
}
alignItems=
"flex-start"
>
<
Field
label=
"Email"
required
size=
{
size
}
helperText=
"Helper text"
maxWidth=
"200px"
>
<
Input
size=
{
size
}
/>
<
Input
/>
</
Field
>
<
Field
label=
"Email (disabled)"
required
size=
{
size
}
maxWidth=
"200px"
>
<
Input
size=
{
size
}
disabled
value=
"me@example.com"
/>
<
Input
disabled
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (readOnly)"
required
size=
{
size
}
maxWidth=
"200px"
>
<
Input
size=
{
size
}
readOnly
value=
"me@example.com"
/>
<
Input
readOnly
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (invalid)"
required
size=
{
size
}
errorText=
"Something went wrong"
invalid
maxWidth=
"200px"
>
<
Input
size=
{
size
}
value=
"duck"
/>
<
Input
value=
"duck"
/>
</
Field
>
</
Sample
>
))
}
<
Sample
label=
"size: xl"
w=
"100%"
alignItems=
"flex-start"
>
<
Field
label=
"Email"
required
floating
size=
"xl"
helperText=
"Helper text"
maxWidth=
"300px"
>
<
Input
size=
"xl"
/>
<
Input
/>
</
Field
>
<
Field
label=
"Email (disabled)"
required
floating
disabled
size=
"xl"
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"me@example.com"
/>
<
Input
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (readOnly)"
required
floating
readOnly
size=
"xl"
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"me@example.com"
/>
<
Input
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (invalid)"
required
floating
size=
"xl"
errorText=
"Something went wrong"
invalid
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"duck"
/>
<
Input
value=
"duck"
/>
</
Field
>
</
Sample
>
</
SamplesStack
>
...
...
@@ -63,16 +63,16 @@ const FieldShowcase = () => {
</
Sample
>
<
Sample
label=
"floating label"
p=
{
4
}
bgColor=
{
{
_light
:
'
blackAlpha.200
'
,
_dark
:
'
whiteAlpha.200
'
}
}
alignItems=
"flex-start"
>
<
Field
label=
"Email"
required
floating
size=
"xl"
helperText=
"Helper text"
maxWidth=
"300px"
>
<
Input
size=
"xl"
/>
<
Input
/>
</
Field
>
<
Field
label=
"Email (disabled)"
required
disabled
floating
size=
"xl"
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"me@example.com"
/>
<
Input
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (readOnly)"
required
readOnly
floating
size=
"xl"
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"me@example.com"
/>
<
Input
value=
"me@example.com"
/>
</
Field
>
<
Field
label=
"Email (invalid)"
required
floating
size=
"xl"
errorText=
"Something went wrong"
invalid
maxWidth=
"300px"
>
<
Input
size=
"xl"
value=
"duck"
/>
<
Input
value=
"duck"
/>
</
Field
>
</
Sample
>
</
SamplesStack
>
...
...
ui/tokenInfo/TokenInfoForm.tsx
View file @
b8789b81
import
{
Button
,
Grid
,
GridItem
,
Text
}
from
'
@chakra-ui/react
'
;
import
{
Grid
,
GridItem
,
Text
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
SubmitHandler
}
from
'
react-hook-form
'
;
import
{
FormProvider
,
useForm
}
from
'
react-hook-form
'
;
...
...
@@ -10,9 +10,10 @@ import config from 'configs/app';
import
type
{
ResourceError
}
from
'
lib/api/resources
'
;
import
useApiFetch
from
'
lib/api/useApiFetch
'
;
import
useApiQuery
from
'
lib/api/useApiQuery
'
;
import
useToast
from
'
lib/hooks/useToast
'
;
import
useUpdateEffect
from
'
lib/hooks/useUpdateEffect
'
;
import
*
as
mixpanel
from
'
lib/mixpanel/index
'
;
import
{
Button
}
from
'
toolkit/chakra/button
'
;
import
{
toaster
}
from
'
toolkit/chakra/toaster
'
;
import
ContentLoader
from
'
ui/shared/ContentLoader
'
;
import
DataFetchAlert
from
'
ui/shared/DataFetchAlert
'
;
import
FormFieldAddress
from
'
ui/shared/forms/fields/FormFieldAddress
'
;
...
...
@@ -42,7 +43,6 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
const
openEventSent
=
React
.
useRef
<
boolean
>
(
false
);
const
apiFetch
=
useApiFetch
();
const
toast
=
useToast
();
const
configQuery
=
useApiQuery
(
'
token_info_applications_config
'
,
{
pathParams
:
{
chainId
:
config
.
chain
.
id
},
...
...
@@ -85,16 +85,12 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
throw
result
;
}
}
catch
(
error
)
{
toast
({
position
:
'
top-right
'
,
toaster
.
error
({
title
:
'
Error
'
,
description
:
(
error
as
ResourceError
<
{
message
:
string
}
>
)?.
payload
?.
message
||
'
Something went wrong. Try again later.
'
,
status
:
'
error
'
,
variant
:
'
subtle
'
,
isClosable
:
true
,
});
}
},
[
apiFetch
,
application
?.
id
,
application
?.
status
,
onSubmit
,
toast
]);
},
[
apiFetch
,
application
?.
id
,
application
?.
status
,
onSubmit
]);
useUpdateEffect
(()
=>
{
if
(
formState
.
submitCount
>
0
&&
!
formState
.
isValid
)
{
...
...
@@ -119,8 +115,8 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
}
const
fieldProps
=
{
size
:
{
base
:
'
md
'
,
lg
:
'
lg
'
}
,
isR
eadOnly
:
application
?.
status
===
'
IN_PROCESS
'
,
size
:
'
xl
'
as
const
,
r
eadOnly
:
application
?.
status
===
'
IN_PROCESS
'
,
};
return
(
...
...
@@ -129,16 +125,16 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
<
TokenInfoFormStatusText
application=
{
application
}
/>
<
Grid
mt=
{
8
}
gridTemplateColumns=
{
{
base
:
'
1fr
'
,
lg
:
'
1fr 1fr
'
}
}
columnGap=
{
5
}
rowGap=
{
5
}
>
<
FormFieldText
<
Fields
>
name="token_name"
isRequired placeholder="Token name"
{
...
fieldProps
}
isR
eadOnly/
>
<
FormFieldAddress
<
Fields
>
name="address"
isRequired placeholder="Token contract address"
{
...
fieldProps
}
isR
eadOnly/
>
<
FormFieldText
<
Fields
>
name="requester_name"
isR
equired placeholder="Requester name"
{
...
fieldProps
}
/
>
<
FormFieldEmail
<
Fields
>
name="requester_email"
isR
equired placeholder="Requester email"
{
...
fieldProps
}
/
>
<
FormFieldText
<
Fields
>
name="token_name"
required placeholder="Token name"
{
...
fieldProps
}
r
eadOnly/
>
<
FormFieldAddress
<
Fields
>
name="address"
required placeholder="Token contract address"
{
...
fieldProps
}
r
eadOnly/
>
<
FormFieldText
<
Fields
>
name="requester_name"
r
equired placeholder="Requester name"
{
...
fieldProps
}
/
>
<
FormFieldEmail
<
Fields
>
name="requester_email"
r
equired placeholder="Requester email"
{
...
fieldProps
}
/
>
<
TokenInfoFormSectionHeader
>
Project info
</
TokenInfoFormSectionHeader
>
<
FormFieldText
<
Fields
>
name="project_name" placeholder="Project name"
{
...
fieldProps
}
rules=
{
nonWhitespaceFieldRules
}
/
>
<
TokenInfoFieldProjectSector
{
...
fieldProps
}
config=
{
configQuery
.
data
.
projectSectors
}
/>
<
FormFieldEmail
<
Fields
>
name="project_email"
isR
equired placeholder="Official project email address"
{
...
fieldProps
}
/
>
<
FormFieldUrl
<
Fields
>
name="project_website"
isR
equired placeholder="Official project website"
{
...
fieldProps
}
/
>
<
FormFieldEmail
<
Fields
>
name="project_email"
r
equired placeholder="Official project email address"
{
...
fieldProps
}
/
>
<
FormFieldUrl
<
Fields
>
name="project_website"
r
equired placeholder="Official project website"
{
...
fieldProps
}
/
>
<
FormFieldUrl
<
Fields
>
name="docs" placeholder="Docs"
{
...
fieldProps
}
/
>
<
TokenInfoFieldSupport
{
...
fieldProps
}
/>
<
GridItem
colSpan=
{
{
base
:
1
,
lg
:
2
}
}
>
...
...
@@ -147,14 +143,14 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
<
GridItem
colSpan=
{
{
base
:
1
,
lg
:
2
}
}
>
<
FormFieldText
<
Fields
>
name="project_description"
isR
equired
r
equired
placeholder="Project description"
maxH="160px"
rules=
{
{
maxLength
:
300
,
...
nonWhitespaceFieldRules
}
}
asComponent="Textarea"
{
...
fieldProps
}
/
>
<
Text
variant=
"
secondary"
fontSize=
"sm"
mt=
{
1
}
>
<
Text
color=
"text.
secondary"
fontSize=
"sm"
mt=
{
1
}
>
Introduce or summarize the project’s operation/goals in a maximum of 300 characters.
The description should be written in a neutral point of view and must exclude unsubstantiated claims unless proven otherwise.
</
Text
>
...
...
@@ -194,9 +190,9 @@ const TokenInfoForm = ({ address, tokenName, application, onSubmit }: Props) =>
type=
"submit"
size=
"lg"
mt=
{
8
}
isL
oading=
{
formState
.
isSubmitting
}
l
oading=
{
formState
.
isSubmitting
}
loadingText=
"Send request"
isD
isabled=
{
application
?.
status
===
'
IN_PROCESS
'
}
d
isabled=
{
application
?.
status
===
'
IN_PROCESS
'
}
>
Send request
</
Button
>
...
...
ui/tokenInfo/TokenInfoFormSectionHeader.tsx
View file @
b8789b81
import
{
GridItem
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
{
Heading
}
from
'
toolkit/chakra/heading
'
;
interface
Props
{
children
:
React
.
ReactNode
;
}
const
TokenInfoFormSectionHeader
=
({
children
}:
Props
)
=>
{
return
(
<
GridItem
colSpan=
{
{
base
:
1
,
lg
:
2
}
}
fontFamily=
"heading"
fontSize=
"lg"
fontWeight=
{
500
}
mt=
{
3
}
>
<
GridItem
colSpan=
{
{
base
:
1
,
lg
:
2
}
}
mt=
{
3
}
>
<
Heading
level=
"2"
>
{
children
}
</
Heading
>
</
GridItem
>
);
};
...
...
ui/tokenInfo/TokenInfoFormStatusText.tsx
View file @
b8789b81
import
{
Alert
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
TokenInfoApplication
}
from
'
types/api/account
'
;
import
{
Alert
}
from
'
toolkit/chakra/alert
'
;
interface
Props
{
application
?:
TokenInfoApplication
;
}
...
...
ui/tokenInfo/TokenInfoIconPreview.tsx
View file @
b8789b81
import
{
Center
,
useColorModeValue
}
from
'
@chakra-ui/react
'
;
import
{
Center
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
interface
Props
{
...
...
@@ -8,13 +8,13 @@ interface Props {
}
const
TokenInfoIconPreview
=
({
url
,
isInvalid
,
children
}:
Props
)
=>
{
const
borderColor
=
useColorModeValue
(
'
gray.100
'
,
'
gray.700
'
)
;
const
borderColorFilled
=
useColorModeValue
(
'
gray.300
'
,
'
gray.600
'
)
;
const
borderColor
=
{
_light
:
'
gray.100
'
,
_dark
:
'
gray.700
'
}
;
const
borderColorFilled
=
{
_light
:
'
gray.300
'
,
_dark
:
'
gray.600
'
}
;
const
borderColorActive
=
isInvalid
?
'
error
'
:
borderColorFilled
;
return
(
<
Center
boxSize=
{
{
base
:
'
60px
'
,
lg
:
'
80px
'
}
}
boxSize=
"60px"
flexShrink=
{
0
}
borderWidth=
"2px"
borderColor=
{
url
?
borderColorActive
:
borderColor
}
...
...
ui/tokenInfo/fields/TokenInfoFieldIconUrl.tsx
View file @
b8789b81
import
type
{
FormControlProps
}
from
'
@chakra-ui/react
'
;
import
{
Flex
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
Fields
}
from
'
../types
'
;
import
{
times
}
from
'
lib/html-entities
'
;
import
type
{
FieldProps
}
from
'
toolkit/chakra/field
'
;
import
ImageUrlPreview
from
'
ui/shared/forms/components/ImageUrlPreview
'
;
import
FormFieldUrl
from
'
ui/shared/forms/fields/FormFieldUrl
'
;
import
useFieldWithImagePreview
from
'
ui/shared/forms/utils/useFieldWithImagePreview
'
;
...
...
@@ -13,11 +13,11 @@ import TokenLogoPlaceholder from 'ui/shared/TokenLogoPlaceholder';
import
TokenInfoIconPreview
from
'
../TokenInfoIconPreview
'
;
interface
Props
{
isR
eadOnly
?:
boolean
;
size
?:
F
ormControl
Props
[
'
size
'
];
r
eadOnly
?:
boolean
;
size
?:
F
ield
Props
[
'
size
'
];
}
const
TokenInfoFieldIconUrl
=
({
isR
eadOnly
,
size
}:
Props
)
=>
{
const
TokenInfoFieldIconUrl
=
({
r
eadOnly
,
size
}:
Props
)
=>
{
const
previewUtils
=
useFieldWithImagePreview
({
name
:
'
icon_url
'
,
isRequired
:
true
});
...
...
@@ -26,15 +26,15 @@ const TokenInfoFieldIconUrl = ({ isReadOnly, size }: Props) => {
<
FormFieldUrl
<
Fields
>
name="icon_url"
placeholder=
{
`Link to icon URL, link to download a SVG or 48${ times }48 PNG icon logo`
}
isReadOnly=
{
isR
eadOnly
}
readOnly=
{
r
eadOnly
}
size=
{
size
}
{
...
previewUtils
.
input
}
/
>
<
TokenInfoIconPreview
url=
{
previewUtils
.
preview
.
src
}
isInvalid=
{
previewUtils
.
preview
.
isInvalid
}
>
<
ImageUrlPreview
{
...
previewUtils
.
preview
}
fallback=
{
<
TokenLogoPlaceholder
boxSize=
{
{
base
:
10
,
lg
:
12
}
}
/>
}
boxSize=
{
{
base
:
10
,
lg
:
12
}
}
fallback=
{
<
TokenLogoPlaceholder
boxSize=
{
10
}
/>
}
boxSize=
{
10
}
borderRadius=
"base"
/>
</
TokenInfoIconPreview
>
...
...
ui/tokenInfo/fields/TokenInfoFieldProjectSector.tsx
View file @
b8789b81
import
{
createListCollection
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
Fields
}
from
'
../types
'
;
import
type
{
TokenInfoApplicationConfig
}
from
'
types/api/account
'
;
import
FormField
FancySelect
from
'
ui/shared/forms/fields/FormFieldFancy
Select
'
;
import
FormField
Select
from
'
ui/shared/forms/fields/FormField
Select
'
;
interface
Props
{
isR
eadOnly
?:
boolean
;
r
eadOnly
?:
boolean
;
config
:
TokenInfoApplicationConfig
[
'
projectSectors
'
];
}
const
TokenInfoFieldProjectSector
=
({
isR
eadOnly
,
config
}:
Props
)
=>
{
const
TokenInfoFieldProjectSector
=
({
r
eadOnly
,
config
}:
Props
)
=>
{
const
options
=
React
.
useMemo
(()
=>
{
return
config
.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}));
const
collection
=
React
.
useMemo
(()
=>
{
const
items
=
config
.
map
((
option
)
=>
({
label
:
option
,
value
:
option
}));
return
createListCollection
({
items
});
},
[
config
]);
return
(
<
FormField
Fancy
Select
<
Fields
,
'
project_sector
'
>
<
FormFieldSelect
<
Fields
,
'
project_sector
'
>
name="project_sector"
placeholder="Project industry"
options=
{
options
}
isReadOnly=
{
isR
eadOnly
}
collection=
{
collection
}
readOnly=
{
r
eadOnly
}
/
>
);
};
...
...
ui/tokenInfo/fields/TokenInfoFieldSocialLink.tsx
View file @
b8789b81
import
type
{
FormControlProps
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
ControllerRenderProps
}
from
'
react-hook-form
'
;
import
type
{
Fields
,
SocialLinkFields
}
from
'
../types
'
;
import
type
{
FieldProps
}
from
'
toolkit/chakra/field
'
;
import
FormFieldUrl
from
'
ui/shared/forms/fields/FormFieldUrl
'
;
import
type
{
IconName
}
from
'
ui/shared/IconSvg
'
;
import
IconSvg
from
'
ui/shared/IconSvg
'
;
...
...
@@ -14,36 +14,38 @@ interface Item {
color
:
string
;
}
const
SETTINGS
:
Record
<
keyof
SocialLinkFields
,
Item
>
=
{
github
:
{
label
:
'
GitHub
'
,
icon
:
'
social/github_filled
'
,
color
:
'
inherit
'
},
github
:
{
label
:
'
GitHub
'
,
icon
:
'
social/github_filled
'
,
color
:
'
text.primary
'
},
telegram
:
{
label
:
'
Telegram
'
,
icon
:
'
social/telegram_filled
'
,
color
:
'
telegram
'
},
linkedin
:
{
label
:
'
LinkedIn
'
,
icon
:
'
social/linkedin_filled
'
,
color
:
'
linkedin
'
},
discord
:
{
label
:
'
Discord
'
,
icon
:
'
social/discord_filled
'
,
color
:
'
discord
'
},
slack
:
{
label
:
'
Slack
'
,
icon
:
'
social/slack_filled
'
,
color
:
'
slack
'
},
twitter
:
{
label
:
'
X (ex-Twitter)
'
,
icon
:
'
social/twitter_filled
'
,
color
:
'
inherit
'
},
twitter
:
{
label
:
'
X (ex-Twitter)
'
,
icon
:
'
social/twitter_filled
'
,
color
:
'
text.primary
'
},
opensea
:
{
label
:
'
OpenSea
'
,
icon
:
'
social/opensea_filled
'
,
color
:
'
opensea
'
},
facebook
:
{
label
:
'
Facebook
'
,
icon
:
'
social/facebook_filled
'
,
color
:
'
facebook
'
},
medium
:
{
label
:
'
Medium
'
,
icon
:
'
social/medium_filled
'
,
color
:
'
inherit
'
},
medium
:
{
label
:
'
Medium
'
,
icon
:
'
social/medium_filled
'
,
color
:
'
text.primary
'
},
reddit
:
{
label
:
'
Reddit
'
,
icon
:
'
social/reddit_filled
'
,
color
:
'
reddit
'
},
};
interface
Props
{
isR
eadOnly
?:
boolean
;
size
?:
F
ormControl
Props
[
'
size
'
];
r
eadOnly
?:
boolean
;
size
?:
F
ield
Props
[
'
size
'
];
name
:
keyof
SocialLinkFields
;
}
const
TokenInfoFieldSocialLink
=
({
isR
eadOnly
,
size
,
name
}:
Props
)
=>
{
const
TokenInfoFieldSocialLink
=
({
r
eadOnly
,
size
,
name
}:
Props
)
=>
{
const
rightElement
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Fields
,
keyof
SocialLink
Fields
>
})
=>
{
return
<
IconSvg
name=
{
SETTINGS
[
name
].
icon
}
boxSize=
{
6
}
color=
{
field
.
value
?
SETTINGS
[
name
].
color
:
'
#718096
'
}
/>;
const
endElement
=
React
.
useCallback
(({
field
}:
{
field
:
ControllerRenderProps
<
Fields
>
})
=>
{
return
<
IconSvg
name=
{
SETTINGS
[
name
].
icon
}
boxSize=
"60px"
px=
{
4
}
color=
{
field
.
value
?
SETTINGS
[
name
].
color
:
'
#718096
'
}
/>;
},
[
name
]);
return
(
<
FormFieldUrl
<
Fields
,
keyof
SocialLinkFields
>
<
FormFieldUrl
<
Fields
>
name=
{
name
}
placeholder=
{
SETTINGS
[
name
].
label
}
rightElement=
{
rightElement
}
isReadOnly=
{
isReadOnly
}
group=
{
{
endElement
,
}
}
readOnly=
{
readOnly
}
size=
{
size
}
/
>
);
...
...
ui/tokenInfo/fields/TokenInfoFieldSupport.tsx
View file @
b8789b81
import
type
{
InputProps
}
from
'
@chakra-ui/react
'
;
import
React
from
'
react
'
;
import
type
{
Fields
}
from
'
../types
'
;
import
type
{
FieldProps
}
from
'
toolkit/chakra/field
'
;
import
FormFieldText
from
'
ui/shared/forms/fields/FormFieldText
'
;
import
{
validator
as
emailValidator
}
from
'
ui/shared/forms/validators/email
'
;
import
{
urlValidator
}
from
'
ui/shared/forms/validators/url
'
;
interface
Props
{
isR
eadOnly
?:
boolean
;
size
?:
Input
Props
[
'
size
'
];
r
eadOnly
?:
boolean
;
size
?:
Field
Props
[
'
size
'
];
}
const
TokenInfoFieldSupport
=
(
props
:
Props
)
=>
{
...
...
ui/tokenInfo/types.ts
View file @
b8789b81
...
...
@@ -6,7 +6,7 @@ export interface Fields extends SocialLinkFields, TickerUrlFields {
requester_name
:
string
;
requester_email
:
string
;
project_name
?:
string
;
project_sector
:
Option
|
null
;
project_sector
:
Array
<
Option
>
|
null
;
project_email
:
string
;
project_website
:
string
;
project_description
:
string
;
...
...
ui/tokenInfo/utils.ts
View file @
b8789b81
...
...
@@ -12,7 +12,7 @@ export function getFormDefaultValues(address: string, tokenName: string, applica
requester_name
:
application
.
requesterName
,
requester_email
:
application
.
requesterEmail
,
project_name
:
application
.
projectName
,
project_sector
:
application
.
projectSector
?
{
value
:
application
.
projectSector
,
label
:
application
.
projectSector
}
:
null
,
project_sector
:
application
.
projectSector
?
[
{
value
:
application
.
projectSector
,
label
:
application
.
projectSector
}
]
:
null
,
project_email
:
application
.
projectEmail
,
project_website
:
application
.
projectWebsite
,
project_description
:
application
.
projectDescription
||
''
,
...
...
@@ -52,7 +52,7 @@ export function prepareRequestBody(data: Fields): Omit<TokenInfoApplication, 'id
projectDescription
:
data
.
project_description
,
projectEmail
:
data
.
project_email
,
projectName
:
data
.
project_name
,
projectSector
:
data
.
project_sector
?.
value
,
projectSector
:
data
.
project_sector
?.
[
0
]?.
value
,
projectWebsite
:
data
.
project_website
,
reddit
:
data
.
reddit
,
requesterEmail
:
data
.
requester_email
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment