Skip to content

Commit 1963ae0

Browse files
committed
Add hardcoded version of TXT records table
1 parent 5f52c61 commit 1963ae0

4 files changed

Lines changed: 186 additions & 25 deletions

File tree

packages/localizations/src/en-US.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,14 @@ export const enUS: LocalizationResource = {
270270
paragraph2:
271271
"We'll verify automatically once the record is live. This usually takes under a minute, though updating an existing TXT record may take a bit longer.",
272272
},
273+
txtRecordTable: {
274+
columns: {
275+
domain: 'Domain',
276+
type: 'Type',
277+
hostName: 'Host / Name',
278+
value: 'Value',
279+
},
280+
},
273281
},
274282
testConfigurationStep: {
275283
title: 'Test your SSO connection',

packages/shared/src/types/elementIds.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ export type FieldId =
3333
| 'idpSsoUrl'
3434
| 'acsUrl'
3535
| 'spEntityId'
36-
| 'web3WalletName';
36+
| 'web3WalletName'
37+
| 'domain';
3738
export type ProfileSectionId =
3839
| 'profile'
3940
| 'username'

packages/shared/src/types/localization.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,6 +1331,14 @@ export type __internal_LocalizationResource = {
13311331
paragraph1: LocalizationValue;
13321332
paragraph2: LocalizationValue;
13331333
};
1334+
txtRecordTable: {
1335+
columns: {
1336+
domain: LocalizationValue;
1337+
type: LocalizationValue;
1338+
hostName: LocalizationValue;
1339+
value: LocalizationValue;
1340+
};
1341+
};
13341342
};
13351343
testConfigurationStep: {
13361344
title: LocalizationValue;

packages/ui/src/components/ConfigureSSO/steps/VerifyDomainStep.tsx

Lines changed: 168 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,30 @@
11
import type React from 'react';
22
import { useState } from 'react';
33

4-
import { Box, Button, Col, descriptors, Flex, Flow, localizationKeys, useLocalizations } from '@/customizables';
4+
import {
5+
Box,
6+
Button,
7+
Col,
8+
descriptors,
9+
Flex,
10+
Flow,
11+
Icon,
12+
localizationKeys,
13+
Spinner,
14+
Table,
15+
Tbody,
16+
Td,
17+
Text,
18+
Th,
19+
Thead,
20+
Tr,
21+
useLocalizations,
22+
} from '@/customizables';
523
import { Field } from '@/elements/FieldControl';
624
import { Form } from '@/elements/Form';
725
import { TagPill } from '@/elements/TagInput';
26+
import { useClipboard } from '@/hooks';
27+
import { Checkmark, Clipboard } from '@/icons';
828
import { useFormControl } from '@/utils/useFormControl';
929

1030
import { Step } from '../elements/Step';
@@ -33,30 +53,46 @@ export const VerifyDomainStep = (): JSX.Element => {
3353
</Wizard>
3454

3555
<Step.Body>
36-
<Step.Section>
37-
{/* TODO -> Trigger mutation to add domain */}
38-
<DomainsField
39-
onSubmit={domain => {
40-
setDomains(prev => [...prev, domain]);
41-
}}
42-
/>
56+
<Step.Section sx={t => ({ gap: t.space.$5 })}>
57+
<Col>
58+
{/* TODO -> Trigger mutation to add domain */}
59+
<DomainsField
60+
onSubmit={domain => {
61+
setDomains(prev => [...prev, domain]);
62+
}}
63+
/>
4364

44-
{domains.length > 0 && (
45-
<Flex
46-
wrap='wrap'
47-
sx={t => ({ gap: t.space.$2, marginTop: t.space.$4 })}
48-
>
49-
{domains.map(domain => (
50-
<TagPill
51-
key={domain}
52-
/* TODO -> Trigger mutation to remove domain */
53-
onRemoveClick={() => setDomains(prev => prev.filter(d => d !== domain))}
54-
>
55-
{domain}
56-
</TagPill>
57-
))}
58-
</Flex>
59-
)}
65+
{domains.length > 0 && (
66+
<Flex
67+
wrap='wrap'
68+
sx={t => ({ gap: t.space.$2, marginTop: t.space.$4 })}
69+
>
70+
{domains.map(domain => (
71+
<TagPill
72+
key={domain}
73+
/* TODO -> Trigger mutation to remove domain */
74+
onRemoveClick={() => setDomains(prev => prev.filter(d => d !== domain))}
75+
>
76+
{domain}
77+
</TagPill>
78+
))}
79+
</Flex>
80+
)}
81+
</Col>
82+
83+
{/* TODO -> Only render when there is existing organization domains */}
84+
<Col sx={t => ({ gap: t.space.$3 })}>
85+
<Col sx={t => ({ gap: t.space.$4 })}>
86+
<Text
87+
localizationKey={localizationKeys('configureSSO.verifyDomainStep.txtRecordInstructions.paragraph1')}
88+
/>
89+
<Text
90+
localizationKey={localizationKeys('configureSSO.verifyDomainStep.txtRecordInstructions.paragraph2')}
91+
/>
92+
</Col>
93+
94+
<TxtRecordTable />
95+
</Col>
6096
</Step.Section>
6197
</Step.Body>
6298
</Step>
@@ -127,3 +163,111 @@ const DomainsField = ({ onSubmit }: { onSubmit: (domain: string) => void }): JSX
127163
*/
128164
const DOMAIN_REGEX = /^(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]{2,}$/i;
129165
const isValidDomain = (value: string): boolean => DOMAIN_REGEX.test(value);
166+
167+
const txtRecordsMock = [
168+
{
169+
domain: 'test.com',
170+
type: 'TXT',
171+
name: '@',
172+
value: 'hellooo-domain-verification-axxn86=sdfsdfsdfsdfdsf',
173+
status: 'pending',
174+
},
175+
{
176+
domain: 'acme.com',
177+
type: 'TXT',
178+
name: '@',
179+
value: 'hellooo2-domain-verification-axxn86=sdfsdfsdfsdfdsf',
180+
status: 'verified',
181+
},
182+
];
183+
184+
const TxtRecordTable = (): JSX.Element => {
185+
return (
186+
<Table>
187+
<Thead>
188+
<Tr>
189+
<Th>Domain</Th>
190+
<Th>Type</Th>
191+
<Th>Host / Name</Th>
192+
<Th>Value</Th>
193+
</Tr>
194+
</Thead>
195+
<Tbody>
196+
{txtRecordsMock.map(record => (
197+
<Tr key={record.domain}>
198+
<Td>
199+
<Flex
200+
as='span'
201+
align='center'
202+
sx={t => ({ gap: t.space.$2 })}
203+
>
204+
{record.status === 'verified' ? (
205+
<Icon
206+
icon={Checkmark}
207+
colorScheme='success'
208+
sx={t => ({ flexShrink: 0, width: t.sizes.$3, height: t.sizes.$3 })}
209+
/>
210+
) : (
211+
<Spinner
212+
size='xs'
213+
colorScheme='neutral'
214+
sx={{ flexShrink: 0 }}
215+
/>
216+
)}
217+
<Text as='span'>{record.domain}</Text>
218+
</Flex>
219+
</Td>
220+
<Td>
221+
<Text as='span'>{record.type}</Text>
222+
</Td>
223+
<Td>
224+
<Text as='span'>{record.name}</Text>
225+
</Td>
226+
<Td sx={{ width: '50%', maxWidth: '1px' }}>
227+
<TxtRecordValueCell value={record.value} />
228+
</Td>
229+
</Tr>
230+
))}
231+
</Tbody>
232+
</Table>
233+
);
234+
};
235+
236+
const TxtRecordValueCell = ({ value }: { value: string }): JSX.Element => {
237+
const { onCopy, hasCopied } = useClipboard(value);
238+
239+
return (
240+
<Flex
241+
align='center'
242+
sx={t => ({ gap: t.space.$2, minWidth: 0 })}
243+
>
244+
<Text
245+
as='span'
246+
colorScheme='secondary'
247+
title={value}
248+
sx={{
249+
fontFamily: 'monospace',
250+
display: 'block',
251+
overflow: 'hidden',
252+
textOverflow: 'ellipsis',
253+
whiteSpace: 'nowrap',
254+
minWidth: 0,
255+
flex: 1,
256+
}}
257+
>
258+
{value}
259+
</Text>
260+
<Button
261+
colorScheme='secondary'
262+
aria-label='Copy value'
263+
onClick={() => onCopy()}
264+
sx={t => ({ flexShrink: 0, padding: t.space.$1 })}
265+
>
266+
<Icon
267+
icon={hasCopied ? Checkmark : Clipboard}
268+
sx={t => ({ width: t.sizes.$4, height: t.sizes.$4, color: t.colors.$colorMutedForeground })}
269+
/>
270+
</Button>
271+
</Flex>
272+
);
273+
};

0 commit comments

Comments
 (0)