Skip to content

Commit c5cbc93

Browse files
committed
Merge branch 'main' into feat/delegation-panel
2 parents 47834b1 + d2c4951 commit c5cbc93

File tree

39 files changed

+1107
-817
lines changed

39 files changed

+1107
-817
lines changed

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "front-aleph-cloud",
3-
"version": "0.35.0",
3+
"version": "0.36.1",
44
"private": true,
55
"scripts": {
66
"dev": "next dev",

scripts/deploy/client.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def main(argv: list[str] | None = None) -> None:
4242

4343
# Fail the workflow on HTTP error codes
4444
if not resp.ok:
45-
print(f"HTTP {resp.status_code}: {resp.text}", file=syzs.stderr)
45+
print(f"HTTP {resp.status_code}: {resp.text}", file=sys.stderr)
4646
sys.exit(1)
4747

4848
try:

src/components/common/DomainDetail/hook.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,14 @@ export function useDomainDetail({
110110
const handleUpdate = useCallback(() => {
111111
if (!domain) throw Err.DomainNotFound
112112

113+
const params = new URLSearchParams({
114+
name: domain.id,
115+
target: domain.target,
116+
ref: domain.ref,
117+
})
118+
113119
router.push(
114-
`${NAVIGATION_URLS.console.settings.domain.new}/?name=${domain.id}`,
120+
`${NAVIGATION_URLS.console.settings.domain.new}/?${params.toString()}`,
115121
)
116122
}, [router, domain])
117123

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
import React, { memo, useEffect, useMemo, useState } from 'react'
2+
import {
3+
Button,
4+
Dropdown,
5+
DropdownOption,
6+
Radio,
7+
RadioGroup,
8+
TextInput,
9+
NoisyContainer,
10+
Tabs,
11+
} from '@aleph-front/core'
12+
import Form from '@/components/form/Form'
13+
import { useNewDomainForm } from './hook'
14+
import { NewDomainFormProps } from './types'
15+
import { CenteredContainer } from '../CenteredContainer'
16+
import { SectionTitle } from '../CompositeTitle'
17+
import ExternalLinkButton from '../ExternalLinkButton'
18+
import ButtonLink from '../ButtonLink'
19+
import {
20+
EntityDomainType,
21+
EntityDomainTypeName,
22+
NAVIGATION_URLS,
23+
} from '@/helpers/constants'
24+
import { StyledSection } from './styles'
25+
26+
export const NewDomainForm = ({
27+
name,
28+
entityId,
29+
entityType,
30+
onSuccess,
31+
variant = 'embedded',
32+
showResourceSelection = false,
33+
}: NewDomainFormProps) => {
34+
const {
35+
entities,
36+
nameCtrl,
37+
targetCtrl,
38+
refCtrl,
39+
errors,
40+
handleSubmit,
41+
setTarget,
42+
setRef,
43+
initialTarget,
44+
} = useNewDomainForm({ name, entityId, entityType, onSuccess })
45+
46+
const getTabIdFromTarget = (target?: EntityDomainType) => {
47+
switch (target) {
48+
case EntityDomainType.Instance:
49+
case EntityDomainType.Program:
50+
case EntityDomainType.Confidential:
51+
return 'compute'
52+
case EntityDomainType.IPFS:
53+
return 'ipfs'
54+
default:
55+
return 'website'
56+
}
57+
}
58+
59+
const [tabId, setTabId] = useState(() => getTabIdFromTarget(initialTarget))
60+
61+
// Update tab when initialTarget becomes available (handles async router query)
62+
useEffect(() => {
63+
if (initialTarget) {
64+
setTabId(getTabIdFromTarget(initialTarget))
65+
}
66+
}, [initialTarget])
67+
68+
const labelResourceType = useMemo(() => {
69+
switch (targetCtrl.field.value) {
70+
case EntityDomainType.Instance:
71+
return 'instance'
72+
case EntityDomainType.Confidential:
73+
return 'confidential'
74+
default:
75+
return 'function'
76+
}
77+
}, [targetCtrl.field.value])
78+
79+
const onTabChange = (newTabId: string) => {
80+
setRef('')
81+
setTabId(newTabId)
82+
if (['website', 'ipfs'].includes(newTabId)) {
83+
setTarget(EntityDomainType.IPFS)
84+
} else {
85+
setTarget(EntityDomainType.Program)
86+
}
87+
}
88+
89+
const isEmbedded = variant === 'embedded'
90+
const Wrapper = isEmbedded ? React.Fragment : CenteredContainer
91+
92+
return (
93+
<Wrapper>
94+
<Form onSubmit={handleSubmit} errors={errors}>
95+
<StyledSection $isEmbedded={isEmbedded}>
96+
<SectionTitle number={1}>Custom domain</SectionTitle>
97+
<p tw="mb-6">
98+
Assign a user-friendly domain to your website, instance or function
99+
to not only simplify access to your web3 application but also
100+
enhance its professional appearance. This is an effective way to
101+
elevate user experience, establish brand identity or streamline the
102+
navigation process within your application.
103+
</p>
104+
<NoisyContainer>
105+
<TextInput
106+
{...nameCtrl.field}
107+
{...nameCtrl.fieldState}
108+
required
109+
label="Enter your desired custom domain in the field below"
110+
placeholder="yourdomain.io"
111+
/>
112+
</NoisyContainer>
113+
<div tw="mt-6 text-right">
114+
<ExternalLinkButton href={NAVIGATION_URLS.docs.customDomains}>
115+
Learn more
116+
</ExternalLinkButton>
117+
</div>
118+
{!showResourceSelection && (
119+
<div tw="mt-10 text-center z-0">
120+
<Button
121+
type="submit"
122+
color="main0"
123+
kind="default"
124+
size="md"
125+
variant="primary"
126+
>
127+
Create domain
128+
</Button>
129+
</div>
130+
)}
131+
</StyledSection>
132+
{showResourceSelection && (
133+
<StyledSection $isEmbedded={isEmbedded}>
134+
<SectionTitle number={2}>Select Resource</SectionTitle>
135+
<p tw="mb-6">
136+
You&apos;ll need to specify the resource your custom domain will
137+
be associated with. This could either be a website, an instance or
138+
a function, depending on what you want your custom domain to point
139+
to.
140+
</p>
141+
<div tw="my-10">
142+
<Tabs
143+
align="left"
144+
selected={tabId}
145+
onTabChange={onTabChange}
146+
tabs={[
147+
{
148+
id: 'website',
149+
name: 'Website',
150+
},
151+
{
152+
id: 'compute',
153+
name: 'Compute',
154+
},
155+
{
156+
id: 'ipfs',
157+
name: 'IPFS',
158+
},
159+
]}
160+
/>
161+
</div>
162+
<div role="tabpanel">
163+
{tabId === 'website' ? (
164+
<NoisyContainer tw="z-10!">
165+
{entities.length > 0 ? (
166+
<Dropdown
167+
{...refCtrl.field}
168+
{...refCtrl.fieldState}
169+
required
170+
label="Link your custom domain to a specific website"
171+
>
172+
{entities.map(({ label, value }) => (
173+
<DropdownOption key={value} value={value}>
174+
{label}
175+
</DropdownOption>
176+
))}
177+
</Dropdown>
178+
) : (
179+
<div>
180+
<p tw="mt-0.5 mb-3 text-black">
181+
If you want to link a domain to a website, you need to
182+
deploy one first *
183+
</p>
184+
<ButtonLink
185+
type="button"
186+
kind="functional"
187+
size="md"
188+
variant="warning"
189+
href={NAVIGATION_URLS.console.web3Hosting.website.new}
190+
>
191+
Create your first website
192+
</ButtonLink>
193+
</div>
194+
)}
195+
</NoisyContainer>
196+
) : tabId === 'compute' ? (
197+
<NoisyContainer tw="z-10!">
198+
<RadioGroup
199+
{...targetCtrl.field}
200+
{...targetCtrl.fieldState}
201+
required
202+
label="Choose resource type"
203+
direction="row"
204+
>
205+
<Radio
206+
label={EntityDomainTypeName[EntityDomainType.Program]}
207+
value={EntityDomainType.Program}
208+
/>
209+
<Radio
210+
label={EntityDomainTypeName[EntityDomainType.Instance]}
211+
value={EntityDomainType.Instance}
212+
/>
213+
<Radio
214+
label={
215+
EntityDomainTypeName[EntityDomainType.Confidential]
216+
}
217+
value={EntityDomainType.Confidential}
218+
/>
219+
</RadioGroup>
220+
{entities.length > 0 ? (
221+
<div tw="mt-10">
222+
<Dropdown
223+
{...refCtrl.field}
224+
{...refCtrl.fieldState}
225+
required
226+
label="Select the specific resource"
227+
>
228+
{entities.map(({ label, value }) => (
229+
<DropdownOption key={value} value={value}>
230+
{label}
231+
</DropdownOption>
232+
))}
233+
</Dropdown>
234+
</div>
235+
) : (
236+
<div>
237+
<p tw="mt-6 mb-3 text-black">
238+
If you want to link a domain to a {labelResourceType},
239+
you need to deploy one first *
240+
</p>
241+
<ButtonLink
242+
type="button"
243+
kind="functional"
244+
size="md"
245+
variant="warning"
246+
href={`/console/computing/${labelResourceType}/new`}
247+
>
248+
{`Create your first ${labelResourceType}` as string}
249+
</ButtonLink>
250+
</div>
251+
)}
252+
</NoisyContainer>
253+
) : tabId === 'ipfs' ? (
254+
<NoisyContainer>
255+
<TextInput
256+
{...refCtrl.field}
257+
{...refCtrl.fieldState}
258+
required
259+
label="Link your custom domain to an Aleph Message ID"
260+
placeholder="Paste your IPFS Aleph Message ID"
261+
/>
262+
</NoisyContainer>
263+
) : (
264+
<></>
265+
)}
266+
</div>
267+
<div tw="mt-10 text-center z-0">
268+
<Button
269+
type="submit"
270+
color="main0"
271+
kind="default"
272+
size="md"
273+
variant="primary"
274+
>
275+
Create domain
276+
</Button>
277+
</div>
278+
</StyledSection>
279+
)}
280+
</Form>
281+
</Wrapper>
282+
)
283+
}
284+
NewDomainForm.displayName = 'NewDomainForm'
285+
286+
export default memo(NewDomainForm) as typeof NewDomainForm

0 commit comments

Comments
 (0)