Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(hooks-store): style hook store #4905

Merged
merged 22 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
3efa291
feat: release drag drop styling
fairlighteth Sep 13, 2024
a3bea71
feat: release drag drop styling + replace lib
fairlighteth Sep 16, 2024
1db67ee
feat: release drag drop styling + replace lib
fairlighteth Sep 16, 2024
5b29070
Merge branch 'develop' into release-drag-drop
fairlighteth Sep 16, 2024
44f2385
Merge branch 'develop' into release-drag-drop
fairlighteth Sep 16, 2024
a510ddf
feat: fix lint
fairlighteth Sep 16, 2024
37bf9b4
Merge branch 'release-drag-drop' of github.com:cowprotocol/cowswap in…
fairlighteth Sep 16, 2024
a698922
feat: fix lint
fairlighteth Sep 16, 2024
fed2fd4
feat: remove unused package
fairlighteth Sep 16, 2024
7324117
feat: hooks store styling
fairlighteth Sep 17, 2024
93e6590
Merge branch 'develop' into hooks-styling-2
fairlighteth Sep 17, 2024
780acd9
feat: mobile responsive updates
fairlighteth Sep 17, 2024
c4a8eea
Merge branch 'hooks-styling-2' of github.com:cowprotocol/cowswap into…
fairlighteth Sep 17, 2024
e9aa316
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Sep 20, 2024
2795c31
chore: merge develop
shoom3301 Sep 20, 2024
a746a36
chore: fix build
shoom3301 Sep 23, 2024
c265ecf
Merge branch 'develop' of https://github.com/cowprotocol/cowswap into…
shoom3301 Sep 23, 2024
fce3b40
chore: fix styles
shoom3301 Sep 23, 2024
6e5dd59
chore: fix styles
shoom3301 Sep 23, 2024
eafb668
chore: fix styles
shoom3301 Sep 23, 2024
602a050
chore: fix build
shoom3301 Sep 23, 2024
51338f1
Update hook.tsx
shoom3301 Sep 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions apps/cowswap-frontend/src/common/pure/NewModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ const ModalInner = styled.div`
background: transparent;
padding: 0;
position: relative;

`

const Wrapper = styled.div<{
Expand All @@ -36,9 +35,6 @@ const Wrapper = styled.div<{

${Media.upToSmall()} {
margin: 0;
border-radius: 0;
border-top-left-radius: var(${UI.BORDER_RADIUS_NORMAL});
border-top-right-radius: var(${UI.BORDER_RADIUS_NORMAL});
box-shadow: none;
}

Expand Down Expand Up @@ -92,7 +88,7 @@ const BackButtonStyled = styled(BackButton)`
left: 10px;
`

const NewModalContent = styled.div<{ padding?: string, justifyContent?: string }>`
const NewModalContent = styled.div<{ padding?: string; justifyContent?: string }>`
display: flex;
justify-content: ${({ justifyContent }) => justifyContent || 'center'};
flex-flow: column wrap;
Expand Down Expand Up @@ -177,7 +173,7 @@ export function NewModal({
const onDismissCallback = useCallback(() => onDismiss?.(), [onDismiss])

return (
<Wrapper maxWidth={maxWidth} minHeight={minHeight} modalMode={modalMode} >
<Wrapper maxWidth={maxWidth} minHeight={minHeight} modalMode={modalMode}>
<ModalInner>
{!modalMode && <BackButtonStyled onClick={onDismissCallback} />}
{title && (
Expand All @@ -191,7 +187,11 @@ export function NewModal({
</Heading>
)}

<NewModalContent className={modalMode ? 'modalMode' : ''} padding={contentPadding} justifyContent={justifyContent}>
<NewModalContent
className={modalMode ? 'modalMode' : ''}
padding={contentPadding}
justifyContent={justifyContent}
>
{children}
</NewModalContent>
</ModalInner>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import buildImg from './build.png'

import { HookDappInternal, HookDappType } from '../../types/hooks'
import { HookDappInternal, HookDappType, HookDappWalletCompatibility } from '../../types/hooks'

import { BuildHookApp } from './index'

const getAppDetails = (isPreHook: boolean): HookDappInternal => {
return {
name: `Build your own ${isPreHook ? 'Pre' : 'Post'}-hook`,
descriptionShort: "Call any smart contract with your own parameters",
descriptionShort: 'Call any smart contract with your own parameters',
description: `Didn't find a suitable hook? You can always create your own! To do this, you need to specify which smart contract you want to call, the parameters for the call and the gas limit.`,
type: HookDappType.INTERNAL,
image: buildImg,
component: (props) => <BuildHookApp {...props} />,
version: 'v0.1.0',
website: 'https://docs.cow.fi/cow-protocol/reference/core/intents/hooks',
walletCompatibility: [HookDappWalletCompatibility.SMART_CONTRACT, HookDappWalletCompatibility.EOA],
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,84 +1,137 @@
import { useCallback, useState } from 'react'

import { capitalizeFirstLetter } from '@cowprotocol/common-utils'
import { ButtonPrimary } from '@cowprotocol/ui'

import { ContentWrapper, Row, Wrapper } from './styled'

import { CowHook, HookDappProps } from '../../types/hooks'
import { ContentWrapper, Row, Wrapper, ErrorText } from '../styled'

const DEFAULT_HOOK_STATE = {
interface FormFieldParams {
name: string
label: string
type: string
rows?: number
}
const DEFAULT_HOOK_STATE: CowHook = {
target: '',
callData: '',
gasLimit: '',
}

const DEFAULT_ERRORS_STATE: Record<keyof CowHook, string> = {
target: '',
callData: '',
gasLimit: '',
}

const FIELDS = [
{ name: 'target', label: 'Target', type: 'text' },
{ name: 'gasLimit', label: 'Gas limit', type: 'number' },
{ name: 'callData', label: 'Calldata', type: 'textarea', rows: 8 },
] as ReadonlyArray<FormFieldParams>

export function BuildHookApp({ context }: HookDappProps) {
const hookToEdit = context.hookToEdit
const isPreHook = context.isPreHook
const [hook, setHook] = useState<CowHook>(hookToEdit?.hook || DEFAULT_HOOK_STATE)
const [errors, setErrors] = useState<Record<keyof CowHook, string>>(DEFAULT_ERRORS_STATE)

const onEditHook = useCallback(() => {
if (!hookToEdit) return
const validateInput = useCallback((name: keyof CowHook, value: string) => {
setErrors((prev) => ({ ...prev, [name]: value.trim() ? '' : `${capitalizeFirstLetter(name)} is required` }))
}, [])

const { callData, gasLimit, target } = hook
if (!callData || !gasLimit || !target) {
return
}
const handleInputChange = useCallback(
({ name, value }: { name: string; value: string }) => {
setHook((prev) => ({ ...prev, [name]: value }))
validateInput(name as keyof CowHook, value)
},
[validateInput],
)

context.editHook({
...hookToEdit,
hook,
const handleSubmit = useCallback(() => {
const newErrors: Record<keyof CowHook, string> = { ...DEFAULT_ERRORS_STATE }

const hasErrors = Object.entries(hook).some(([key, value]) => {
if (!value.trim()) {
newErrors[key as keyof CowHook] = `${capitalizeFirstLetter(key)} is required`
return true
}
return false
})
}, [hook, context, hookToEdit])

const clickOnAddHook = useCallback(() => {
const { callData, gasLimit, target } = hook
if (!callData || !gasLimit || !target) {
if (hasErrors) {
setErrors(newErrors)
return
}

context.addHook({ hook })
}, [hook, context])
hookToEdit
? context.editHook({
...hookToEdit,
hook,
})
: context.addHook({ hook })
}, [hook, context, hookToEdit, isPreHook])

return (
<Wrapper>
<ContentWrapper>
<Row>
<label>Target</label>
<div>
<input
name="target"
value={hook.target}
onChange={(e) => setHook((hook) => ({ ...hook, target: e.target.value }))}
/>
</div>
</Row>
<Row>
<label>Gas Limit</label>
<div>
<input
name="gasLimit"
value={hook.gasLimit}
onChange={(e) => setHook((hook) => ({ ...hook, gasLimit: e.target.value }))}
{FIELDS.map((params) => {
return (
<FormField
key={params.name}
params={params}
value={hook[params.name as keyof CowHook]}
error={errors[params.name as keyof CowHook]}
onChange={handleInputChange}
/>
</div>
</Row>

<Row>
<label>Calldata</label>
<div>
<textarea
name="callData"
value={hook.callData}
onChange={(e) => setHook((hook) => ({ ...hook, callData: e.target.value }))}
/>
</div>
</Row>
)
})}
</ContentWrapper>
{hookToEdit ? (
<ButtonPrimary onClick={onEditHook}>Save changes</ButtonPrimary>
) : (
<ButtonPrimary onClick={clickOnAddHook}>Add {context.isPreHook ? 'Pre' : 'Post'}-hook</ButtonPrimary>
)}
<ButtonPrimary onClick={handleSubmit}>
{hookToEdit ? 'Save changes' : `Add ${isPreHook ? 'Pre' : 'Post'}-hook`}
</ButtonPrimary>
</Wrapper>
)
}

interface FormFieldProps {
params: FormFieldParams
value: string
error: string
onChange(value: { name: string; value: string }): void
}

function FormField({ params, value, error, onChange }: FormFieldProps) {
const { name, label, type, rows } = params
return (
<>
<Row key={name}>
{type === 'textarea' ? (
<textarea
name={name}
placeholder=" "
value={value}
onChange={(e) => onChange(e.target)}
className={error ? 'error' : ''}
required
rows={rows}
/>
) : (
<input
type={type}
name={name}
placeholder=" "
value={value}
onChange={(e) => onChange(e.target)}
className={error ? 'error' : ''}
required
/>
)}
<label htmlFor={name} className={error ? 'error' : ''}>
{label}*
</label>
</Row>
{error && <ErrorText>{error}</ErrorText>}
</>
)
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import gnoLogo from '@cowprotocol/assets/cow-swap/network-gnosis-chain-logo.svg'

import { HookDappInternal, HookDappType } from '../../types/hooks'
import { HookDappInternal, HookDappType, HookDappWalletCompatibility } from '../../types/hooks'

import { ClaimGnoHookApp } from './index'

Expand All @@ -9,23 +9,21 @@ export const PRE_CLAIM_GNO: HookDappInternal = {
descriptionShort: 'Withdraw rewards from your Gnosis validators.',
description: (
<>
This hook allows you to withdraw rewards from your Gnosis Chain validators
through CowSwap. It automates the process of interacting with the Gnosis
Deposit Contract, enabling you to claim any available rewards directly to
This hook allows you to withdraw rewards from your Gnosis Chain validators through CoW Swap. It automates the
process of interacting with the Gnosis Deposit Contract, enabling you to claim any available rewards directly to
your specified withdrawal address.
<br />
<br />
The hook monitors your validator's accrued rewards and triggers the
claimWithdrawals function when rewards are ready for withdrawal. This
simplifies the management of Gnosis validator earnings without requiring
ready for withdrawal. This simplifies the management of Gnosis validator
earnings without requiring manual contract interaction, providing a
smoother and more efficient experience for users.
The hook monitors your validator's accrued rewards and triggers the claimWithdrawals function when rewards are
ready for withdrawal. This simplifies the management of Gnosis validator earnings without requiring ready for
withdrawal. This simplifies the management of Gnosis validator earnings without requiring manual contract
interaction, providing a smoother and more efficient experience for users.
</>
),
type: HookDappType.INTERNAL,
component: (props) => <ClaimGnoHookApp {...props} />,
image: gnoLogo,
version: 'v0.1.1',
website: 'https://www.gnosis.io/',
walletCompatibility: [HookDappWalletCompatibility.SMART_CONTRACT, HookDappWalletCompatibility.EOA],
}
Loading
Loading