Skip to content

Commit

Permalink
feat: Enable T&C in create instance message (#112)
Browse files Browse the repository at this point in the history
* deps: upgrade sdk message to v1.3.1

* feat: send terms_and_conditions on VM creation

* docs: explain why modalOpen and modalClose are excluded from deps

* fix: don't show modal when switch to hold
  • Loading branch information
gmolki authored Jan 29, 2025
1 parent c81595a commit 0194eb2
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 82 deletions.
14 changes: 7 additions & 7 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"@aleph-sdk/core": "^1.2.0",
"@aleph-sdk/ethereum": "^1.2.0",
"@aleph-sdk/evm": "^1.2.0",
"@aleph-sdk/message": "^1.3.0",
"@aleph-sdk/message": "^1.3.1",
"@aleph-sdk/solana": "^1.2.1",
"@aleph-sdk/superfluid": "^1.2.0",
"@fortawesome/fontawesome-svg-core": "^6.3.0",
Expand Down
30 changes: 14 additions & 16 deletions src/components/pages/computing/NewInstancePage/cmp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@ const CheckoutButton = React.memo(
title = 'Create instance',
tooltipContent,
isFooter,
termsAndConditions,
shouldRequestTermsAndConditions,
handleRequestTermsAndConditionsAgreement,
handleSubmit,
}: {
disabled: boolean
title?: string
tooltipContent?: TooltipProps['content']
isFooter: boolean
termsAndConditions?: string
shouldRequestTermsAndConditions?: boolean
handleRequestTermsAndConditionsAgreement: UseNewInstancePageReturn['handleRequestTermsAndConditionsAgreement']
handleSubmit: UseNewInstancePageReturn['handleSubmit']
}) => {
Expand All @@ -70,14 +70,14 @@ const CheckoutButton = React.memo(
<>
<Button
ref={checkoutButtonRef}
type={!!termsAndConditions ? 'button' : 'submit'}
type={shouldRequestTermsAndConditions ? 'button' : 'submit'}
color="main0"
kind="default"
size="lg"
variant="primary"
disabled={disabled}
onClick={
!!termsAndConditions
shouldRequestTermsAndConditions
? handleRequestTermsAndConditionsAgreement
: handleSubmit
}
Expand Down Expand Up @@ -121,6 +121,7 @@ export default function NewInstancePage({ mainRef }: PageProps) {
selectedNode,
setSelectedNode,
termsAndConditions,
shouldRequestTermsAndConditions,
modalOpen,
modalClose,
handleManuallySelectCRN,
Expand All @@ -131,13 +132,11 @@ export default function NewInstancePage({ mainRef }: PageProps) {
handleRequestTermsAndConditionsAgreement,
handleAcceptTermsAndConditions,
handleCheckTermsAndConditions,
handleDownloadFile,
} = useNewInstancePage()

const sectionNumber = useCallback((n: number) => (node ? 1 : 0) + n, [node])

// ------------------

// Handle modals
useEffect(
() => {
Expand Down Expand Up @@ -193,14 +192,7 @@ export default function NewInstancePage({ mainRef }: PageProps) {
I have read, understood, and agree to the{' '}
<ExternalLink
text="Terms & Conditions"
href="#"
target="_self"
onClick={() =>
handleDownloadFile(
termsAndConditions.cid,
termsAndConditions.name,
)
}
href={termsAndConditions.url}
color="main0"
typo="body3"
underline
Expand Down Expand Up @@ -249,6 +241,12 @@ export default function NewInstancePage({ mainRef }: PageProps) {
handleCloseModal,
handleCheckTermsAndConditions,
handleAcceptTermsAndConditions,
/*
Both modalOpen and modalClose are not included in the dependencies because there's
an infinite refresh loop when they are included. This is because the modalOpen
and modalClose functions are being redefined on every render, causing the
useEffect to run again and again.
*/
// modalOpen,
// modalClose,
],
Expand Down Expand Up @@ -574,7 +572,7 @@ export default function NewInstancePage({ mainRef }: PageProps) {
title={createInstanceButtonTitle}
tooltipContent={createInstanceDisabledMessage}
isFooter={false}
termsAndConditions={node?.terms_and_conditions}
shouldRequestTermsAndConditions={shouldRequestTermsAndConditions}
handleRequestTermsAndConditionsAgreement={
handleRequestTermsAndConditionsAgreement
}
Expand All @@ -587,7 +585,7 @@ export default function NewInstancePage({ mainRef }: PageProps) {
title={createInstanceButtonTitle}
tooltipContent={createInstanceDisabledMessage}
isFooter={true}
termsAndConditions={node?.terms_and_conditions}
shouldRequestTermsAndConditions={shouldRequestTermsAndConditions}
handleRequestTermsAndConditionsAgreement={
handleRequestTermsAndConditionsAgreement
}
Expand Down
25 changes: 25 additions & 0 deletions src/components/pages/dashboard/ManageInstance/cmp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import LogsFeed from '../LogsFeed'
export default function ManageInstance() {
const {
instance,
termsAndConditions,
status,
mappedKeys,
nodeDetails,
Expand Down Expand Up @@ -332,6 +333,30 @@ export default function ManageInstance() {
<VolumeList {...{ volumes }} />
</>
)}

{termsAndConditions !== undefined && (
<>
<Separator />
<TextGradient type="h7" as="h2" color="main0">
Terms & Conditions
</TextGradient>
<div tw="my-5">
<div className="tp-info text-main0">ACCEPTED T&C</div>
<div>
<a
className="tp-body1 fs-16"
href={termsAndConditions.url}
target="_blank"
referrerPolicy="no-referrer"
>
<IconText iconName="square-up-right">
<Text>{termsAndConditions.name}</Text>
</IconText>
</a>
</div>
</div>
</>
)}
</>
) : tabId === 'log' ? (
<>
Expand Down
13 changes: 11 additions & 2 deletions src/domain/executable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,10 +700,19 @@ export abstract class ExecutableManager {

protected parseRequirements(node?: CRN): HostRequirements | undefined {
if (!node || !node.hash) return
return {

const requirements = {
node: {
node_hash: node.hash,
},
}
} as HostRequirements

if (node.terms_and_conditions)
requirements.node = {
...requirements.node,
terms_and_conditions: node.terms_and_conditions,
}

return requirements
}
}
76 changes: 76 additions & 0 deletions src/hooks/common/useFetchTermsAndConditions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { useAppState } from '@/contexts/appState'
import { StoreContent } from '@aleph-sdk/message'
import { useEffect, useState } from 'react'

export type TermsAndConditions = {
cid: string
name: string
url: string
}

export type UseFetchTermsAndConditionsProps = {
termsAndConditionsMessageHash?: string
}

export type UseFetchTermsAndConditionsReturn = {
loading: boolean
termsAndConditions?: TermsAndConditions
}

export default function useFetchTermsAndConditions({
termsAndConditionsMessageHash,
}: UseFetchTermsAndConditionsProps): UseFetchTermsAndConditionsReturn {
const [state] = useAppState()
const {
manager: { messageManager },
} = state

const [loading, setLoading] = useState(true)
const [termsAndConditions, setTermsAndConditions] = useState<
TermsAndConditions | undefined
>()

useEffect(() => {
const fetchTermsAndConditions = async () => {
try {
if (!messageManager) return setTermsAndConditions(undefined)
if (!termsAndConditionsMessageHash)
return setTermsAndConditions(undefined)

setLoading(true)

let storeMessageContent
try {
const { content } = await messageManager.get(
termsAndConditionsMessageHash,
)
storeMessageContent = content as StoreContent
} catch (e) {
console.error(e)
}

if (!storeMessageContent) return setTermsAndConditions(undefined)

const cid = storeMessageContent.item_hash
const name = storeMessageContent.metadata?.name as string

setTermsAndConditions({
cid,
name,
url: `https://ipfs.aleph.im/ipfs/${cid}?filename=${name}`,
})
} catch (e) {
console.error(e)
} finally {
setLoading(false)
}
}

fetchTermsAndConditions()
}, [messageManager, termsAndConditionsMessageHash])

return {
loading,
termsAndConditions,
}
}
Loading

0 comments on commit 0194eb2

Please sign in to comment.