Skip to content

Commit b762503

Browse files
author
Herman Wikner
authoredJul 9, 2021
refactor(default-login): migrate to @sanity/ui (#2608)
* chore(default-login): add `@sanity/ui` and `@sanity/logos` as dependencies * refactor(default-login): add parts to `legacyParts` file * refactor(default-login): migrate `LoginDialog` to `@sanity/ui` * refactor(default-login): migrate `LoginDialogContent` to `@sanity/ui` * refactor(default-login): migrate `LoginWrapper` to `@sanity/ui` * refactor(default-login): migrate `CookieTest` to `@sanity/ui` * refactor(default-login): migrate `UnauthorizedUser` to `@sanity/ui` * refactor(default-login): migrate `ErrorDialog` to `@sanity/ui` * refactor(default-login): migrate `CorsCheck` to `@sanity/ui`
1 parent 7518562 commit b762503

15 files changed

+375
-443
lines changed
 
+1-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
11
{
22
"extends": "../../../.babelrc",
3-
"presets": ["@babel/react"]
4-
}
3+
"presets": ["@babel/react", "@babel/typescript"]}

‎packages/@sanity/default-login/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
"sanity-plugin"
1919
],
2020
"dependencies": {
21+
"@sanity/ui": "^0.34.2",
22+
"@sanity/logos": "^1.1.2",
2123
"@sanity/generate-help-url": "2.2.6",
2224
"prop-types": "^15.6.0",
2325
"rxjs": "^6.5.3"

‎packages/@sanity/default-login/src/CookieTest.js

+76-40
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,25 @@
11
import PropTypes from 'prop-types'
22
import React, {PureComponent} from 'react'
33
import config from 'config:sanity'
4-
import Button from 'part:@sanity/components/buttons/default'
5-
import BrandLogo from 'part:@sanity/base/brand-logo?'
6-
import Spinner from 'part:@sanity/components/loading/spinner'
74
import {of} from 'rxjs'
85
import {mapTo, catchError, finalize} from 'rxjs/operators'
9-
import styles from './styles/CookieTest.css'
6+
import {Container, Text, Button, Heading, Flex, Stack, Spinner} from '@sanity/ui'
7+
import styled from 'styled-components'
8+
import {BrandLogo} from './legacyParts'
109

1110
import {openCenteredPopup} from './util/openWindow'
1211
import {versionedClient} from './versionedClient'
1312

13+
const BrandLogoWrapper = styled(Flex)`
14+
height: 3em;
15+
16+
svg {
17+
height: 4em;
18+
width: auto;
19+
max-width: 70vw;
20+
}
21+
`
22+
1423
const projectName = (config.project && config.project.name) || ''
1524

1625
const checkCookies = () => {
@@ -93,54 +102,81 @@ class CookieTest extends PureComponent {
93102
}
94103

95104
renderCookieAcceptContent() {
96-
// eslint-disable-line class-methods-use-this
97105
const {SanityLogo, sanityLogo} = this.props
98106
return (
99-
<div className={styles.root}>
100-
<div className={styles.inner}>
107+
<Container width={1} paddingX={3} paddingY={6}>
108+
<Stack space={7}>
101109
{SanityLogo && (
102-
<div className={styles.sanityLogo}>
103-
<SanityLogo />
104-
</div>
110+
<Flex justify="center">
111+
<Text>
112+
<SanityLogo />
113+
</Text>
114+
</Flex>
105115
)}
106-
{sanityLogo && !SanityLogo && <div className={styles.sanityLogo}>{sanityLogo}</div>}
107-
<div className={styles.branding}>
108-
<h1 className={BrandLogo ? styles.projectNameHidden : styles.projectName}>
116+
{sanityLogo && !SanityLogo && (
117+
<Flex justify="center">
118+
<Text>
119+
<SanityLogo />
120+
</Text>
121+
</Flex>
122+
)}
123+
124+
{!BrandLogo && projectName && (
125+
<Heading align="center" as="h1" size={4}>
109126
{projectName}
110-
</h1>
111-
{BrandLogo && (
112-
<div className={styles.brandLogoContainer}>
113-
<BrandLogo projectName={projectName} />
114-
</div>
115-
)}
116-
</div>
117-
118-
<div className={styles.title}>
119-
<h3>We couldn{"'"}t log you in</h3>
120-
</div>
121-
<div className={styles.description}>
122-
<p>Your browser wouldn{"'"}t accept our cookie.</p>
123-
</div>
124-
<div className={styles.button}>
125-
<Button
126-
color="success"
127-
inverted
128-
type="submit"
129-
onClick={this.handleAcceptCookieButtonClicked}
130-
>
131-
Try Again
132-
</Button>
133-
</div>
134-
</div>
135-
</div>
127+
</Heading>
128+
)}
129+
130+
{BrandLogo && projectName && (
131+
<BrandLogoWrapper justify="center">
132+
<BrandLogo projectName={projectName} />
133+
</BrandLogoWrapper>
134+
)}
135+
136+
<Stack space={5}>
137+
<Stack space={4}>
138+
<Text
139+
align="center"
140+
as="h2"
141+
size={3}
142+
weight="semibold"
143+
style={{textTransform: 'uppercase'}}
144+
>
145+
We couldn't log you in
146+
</Text>
147+
148+
<Text size={1} muted align="center">
149+
Your browser wouldn't accept our cookie.
150+
</Text>
151+
</Stack>
152+
153+
<Flex justify="center">
154+
<Button
155+
text="Try again"
156+
tone="positive"
157+
mode="ghost"
158+
onClick={this.handleAcceptCookieButtonClicked}
159+
/>
160+
</Flex>
161+
</Stack>
162+
</Stack>
163+
</Container>
136164
)
137165
}
138166

139167
render() {
140168
const {isLoading, isCookieError} = this.state
141169

142170
if (isLoading) {
143-
return <Spinner fullscreen center />
171+
return (
172+
<Container width={4} padding={4} height="fill">
173+
<Flex align="center" justify="center" height="fill">
174+
<Text>
175+
<Spinner />
176+
</Text>
177+
</Flex>
178+
</Container>
179+
)
144180
}
145181

146182
if (isCookieError) {

‎packages/@sanity/default-login/src/CorsCheck.js

+22-14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import React, {useState, useEffect} from 'react'
2-
import Spinner from 'part:@sanity/components/loading/spinner'
2+
import {Text, Container, Flex, Spinner, Stack} from '@sanity/ui'
33
import {versionedClient} from './versionedClient'
44

55
const checkCors = () =>
@@ -25,7 +25,7 @@ function CorsWrapper({result, children}) {
2525

2626
return (
2727
<div>
28-
<p>Error message:</p>
28+
<Text>Error message:</Text>
2929
<pre>
3030
<code>{response.body.message}</code>
3131
</pre>
@@ -52,7 +52,15 @@ export default function CorsCheck() {
5252
window.location.href.replace(new RegExp(`${window.location.pathname}$`), '')
5353

5454
if (isLoading) {
55-
return <Spinner fullscreen center />
55+
return (
56+
<Container width={4} padding={4} height="fill">
57+
<Flex align="center" justify="center" height="fill">
58+
<Text>
59+
<Spinner />
60+
</Text>
61+
</Flex>
62+
</Container>
63+
)
5664
}
5765

5866
const tld = versionedClient.config().apiHost.replace(/.*?sanity\.([a-z]+).*/, '$1')
@@ -65,20 +73,20 @@ export default function CorsCheck() {
6573
const errType = response.body.attributes && response.body.attributes.type
6674
if (is404 && errType === 'project') {
6775
return (
68-
<div>
69-
<p>{response.body.message || response.statusCode}</p>
70-
<p>
76+
<Stack space={4}>
77+
<Text accent>{response.body.message || response.statusCode}</Text>
78+
<Text accent>
7179
Double-check that your <code>sanity.json</code> points to the right project ID!
72-
</p>
73-
</div>
80+
</Text>
81+
</Stack>
7482
)
7583
}
7684
}
7785

7886
if (result.isCorsError) {
7987
return (
8088
<CorsWrapper result={state.result}>
81-
<p>
89+
<Text accent>
8290
It looks like the error is being caused by the current origin (<code>{origin}</code>) not
8391
being allowed for this project. If you are a project administrator or developer, you can
8492
head to{' '}
@@ -94,30 +102,30 @@ export default function CorsCheck() {
94102
<em>CORS Origins</em>
95103
</a>{' '}
96104
section. Do remember to <code>allow credentials</code>!
97-
</p>
105+
</Text>
98106
</CorsWrapper>
99107
)
100108
}
101109

102110
if (result.pingResponded) {
103111
return (
104112
<CorsWrapper result={state.result}>
105-
<p>
113+
<Text accent>
106114
Our diagnostics cannot quite determine why this happened. If it was a network glitch you
107115
could try hitting the <strong>Retry</strong> button below. If you are working as a
108116
developer on this project, you could also have a look at the browser's dev console and see
109117
if any issues are listed there.
110-
</p>
118+
</Text>
111119
</CorsWrapper>
112120
)
113121
}
114122

115123
return (
116124
<CorsWrapper result={state.result}>
117-
<p>
125+
<Text accent>
118126
It might be that your internet connection is unstable or down. You could try hitting the{' '}
119127
<strong>Retry</strong> button to see if it was just a temporary glitch.
120-
</p>
128+
</Text>
121129
</CorsWrapper>
122130
)
123131
}

‎packages/@sanity/default-login/src/ErrorDialog.js

+27-16
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,39 @@
11
import PropTypes from 'prop-types'
22
import React from 'react'
3-
import FullscreenMessageDialog from 'part:@sanity/components/dialogs/fullscreen-message'
4-
import Button from 'part:@sanity/components/buttons/default'
3+
import {Dialog as UIDialog, Box, Text, Button, Stack} from '@sanity/ui'
4+
import styled from 'styled-components'
55
import CorsCheck from './CorsCheck'
66

7+
const Dialog = styled(UIDialog)`
8+
/* @todo: Temp solution. Update sanity/ui with option to hide close button */
9+
[aria-label='Close dialog'] {
10+
display: none;
11+
}
12+
`
713
export default function ErrorDialog(props) {
814
const isNetworkError = props.error.isNetworkError
915

1016
return (
11-
<FullscreenMessageDialog
12-
buttons={<Button onClick={props.onRetry}>Retry</Button>}
13-
color="danger"
14-
title="Error"
15-
isOpen
16-
centered
17+
<Dialog
18+
header="Error"
19+
cardShadow={2}
20+
width={1}
21+
footer={
22+
<Box padding={3}>
23+
<Button text="Retry" onClick={props.onRetry} style={{width: '100%'}} />
24+
</Box>
25+
}
1726
>
18-
{!isNetworkError && <p>{props.error.message}</p>}
19-
{isNetworkError && (
20-
<>
21-
<p>An error occured while attempting to reach the Sanity API.</p>
22-
<CorsCheck />
23-
</>
24-
)}
25-
</FullscreenMessageDialog>
27+
<Box padding={4}>
28+
{!isNetworkError && <Text accent>{props.error.message}</Text>}
29+
{isNetworkError && (
30+
<Stack space={4}>
31+
<Text accent>An error occurred while attempting to reach the Sanity API.</Text>
32+
<CorsCheck />
33+
</Stack>
34+
)}
35+
</Box>
36+
</Dialog>
2637
)
2738
}
2839

‎packages/@sanity/default-login/src/LoginDialog.js

+46-29
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,22 @@
11
/* eslint-disable react/no-multi-comp */
22
import React from 'react'
33
import PropTypes from 'prop-types'
4-
import authenticationFetcher from 'part:@sanity/base/authentication-fetcher'
5-
import pluginConfig from 'config:@sanity/default-login'
6-
import FullscreenDialog from 'part:@sanity/components/dialogs/fullscreen'
7-
import LoginDialogContent from 'part:@sanity/base/login-dialog-content'
84
import generateHelpUrl from '@sanity/generate-help-url'
9-
import styles from './styles/LoginDialog.css'
5+
import {Dialog as UIDialog, Text, Box, Stack, Container} from '@sanity/ui'
6+
import styled, {css} from 'styled-components'
107
import cancelWrap from './cancelWrap'
8+
import {authenticationFetcher, pluginConfig, LoginDialogContent} from './legacyParts'
9+
10+
const Dialog = styled(UIDialog)`
11+
${({hideClose}) =>
12+
hideClose &&
13+
css`
14+
/* @todo: Temp solution. Update sanity/ui with option to hide close button */
15+
[aria-label='Close dialog'] {
16+
display: none;
17+
}
18+
`}
19+
`
1120

1221
export default class LoginDialog extends React.Component {
1322
static propTypes = {
@@ -92,38 +101,46 @@ export default class LoginDialog extends React.Component {
92101

93102
if (error) {
94103
return (
95-
<FullscreenDialog
96-
color="danger"
97-
title="Error"
98-
isOpen
99-
centered
100-
onClose={error.hideClose ? undefined : this.handleErrorDialogClosed}
104+
<Dialog
105+
header="Error"
106+
width={5}
107+
onClose={error?.hideClose ? undefined : this.handleErrorDialogClosed}
108+
onClickOutside={error?.hideClose ? undefined : this.handleErrorDialogClosed}
109+
cardShadow={2}
101110
>
102-
<div className={styles.error}>
103-
{error.message}
104-
{error.link && (
105-
<p>
106-
<a href={error.link}>Read more</a>
107-
</p>
108-
)}
109-
</div>
110-
</FullscreenDialog>
111+
<Box padding={4}>
112+
<Stack space={4}>
113+
<Text>{error?.message}</Text>
114+
{error?.link && (
115+
<Text>
116+
<a href={error.link}>Read more</a>
117+
</Text>
118+
)}
119+
</Stack>
120+
</Box>
121+
</Dialog>
111122
)
112123
}
113124

114-
if (isLoaded && providers.length === 0) {
115-
return <div>No providers configured</div>
125+
if (isLoaded && providers?.length === 0) {
126+
return (
127+
<Container padding={4} width={4}>
128+
<Text>No providers configured</Text>
129+
</Container>
130+
)
116131
}
117132

118133
if (isLoaded && !shouldRedirect) {
119134
return (
120-
<LoginDialogContent
121-
title={title}
122-
description={description}
123-
providers={providers}
124-
SanityLogo={SanityLogo}
125-
onLoginButtonClick={this.handleLoginButtonClicked}
126-
/>
135+
<Dialog header="Sign in" width={1} cardShadow={2} hideClose>
136+
<LoginDialogContent
137+
title={title}
138+
description={description}
139+
providers={providers}
140+
SanityLogo={SanityLogo}
141+
onLoginButtonClick={this.handleLoginButtonClicked}
142+
/>
143+
</Dialog>
127144
)
128145
}
129146
return null
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,32 @@
1+
/* eslint-disable react/jsx-no-bind */
12
/* eslint-disable react/no-multi-comp */
23
import React from 'react'
34
import PropTypes from 'prop-types'
45
import config from 'config:sanity'
5-
import BrandLogo from 'part:@sanity/base/brand-logo?'
6-
import styles from './styles/LoginDialogContent.css'
6+
import {Button, Stack, Heading, Inline, Flex, Text, Box, Card} from '@sanity/ui'
7+
import styled from 'styled-components'
8+
import {BrandLogo} from './legacyParts'
9+
import {getProviderLogo} from './util/getProviderLogo'
710

8-
const projectName = (config.project && config.project.name) || ''
9-
10-
/* eslint-disable max-len */
11-
const GithubLogo = () => (
12-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 438.55 438.55">
13-
<path d="M409.13 114.57a218.32 218.32 0 0 0-79.8-79.8Q278.94 5.36 219.27 5.36T109.21 34.77a218.29 218.29 0 0 0-79.8 79.8Q0 165 0 224.63q0 71.67 41.83 128.91t108.06 79.23q7.71 1.43 11.42-2a11.17 11.17 0 0 0 3.69-8.57q0-.86-.14-15.42t-.14-25.41l-6.57 1.14a83.77 83.77 0 0 1-15.85 1 120.73 120.73 0 0 1-19.84-2 44.34 44.34 0 0 1-19.11-8.51 36.23 36.23 0 0 1-12.56-17.6l-2.86-6.57a71.34 71.34 0 0 0-9-14.56q-6.14-8-12.42-10.85l-2-1.43a21 21 0 0 1-3.71-3.43 15.66 15.66 0 0 1-2.57-4q-.86-2 1.43-3.29C61.2 310.42 64 310 68 310l5.71.85q5.71 1.14 14.13 6.85a46.08 46.08 0 0 1 13.85 14.84q6.57 11.71 15.85 17.85t18.7 6.14a81.19 81.19 0 0 0 16.27-1.42 56.78 56.78 0 0 0 12.85-4.29q2.57-19.14 14-29.41a195.49 195.49 0 0 1-29.36-5.13 116.52 116.52 0 0 1-26.83-11.14 76.86 76.86 0 0 1-23-19.13q-9.14-11.42-15-30t-5.8-42.81q0-34.55 22.56-58.82-10.57-26 2-58.24 8.28-2.57 24.55 3.85t23.84 11q7.57 4.56 12.13 7.71a206.2 206.2 0 0 1 109.64 0l10.85-6.85a153.65 153.65 0 0 1 26.26-12.56q15.13-5.71 23.13-3.14 12.84 32.26 2.28 58.24 22.55 24.27 22.56 58.82 0 24.27-5.85 43t-15.12 30a79.82 79.82 0 0 1-23.13 19 116.74 116.74 0 0 1-26.84 11.14 195.29 195.29 0 0 1-29.23 5.07q14.8 12.84 14.81 40.58v60.2a11.37 11.37 0 0 0 3.57 8.56q3.57 3.42 11.28 2 66.24-22 108.07-79.23t41.83-128.91q-.03-59.62-29.43-110.05z" />
14-
</svg>
15-
)
16-
17-
const GoogleLogo = () => (
18-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
19-
<path
20-
d="M11 24a13 13 0 0 1 .66-4.08l-7.4-5.66a22.18 22.18 0 0 0 0 19.49l7.4-5.67A13 13 0 0 1 11 24z"
21-
fill="#fbbc05"
22-
/>
23-
<path
24-
d="M24 11a12.72 12.72 0 0 1 8.1 2.9l6.4-6.4a22 22 0 0 0-34.24 6.75l7.4 5.66A13 13 0 0 1 24 11z"
25-
fill="#ea4335"
26-
/>
27-
<path
28-
d="M24 37a13 13 0 0 1-12.34-8.92l-7.4 5.66A21.93 21.93 0 0 0 24 46a21 21 0 0 0 14.33-5.48l-7-5.44A13.59 13.59 0 0 1 24 37zm-12.35-8.93l-7.4 5.67 7.4-5.66z"
29-
fill="#34a853"
30-
/>
31-
<path
32-
d="M44.5 20H24v8.5h11.8a9.91 9.91 0 0 1-4.49 6.58l7 5.44C42.37 36.76 45 31.17 45 24a18.25 18.25 0 0 0-.5-4z"
33-
fill="#4285f4"
34-
/>
35-
</svg>
36-
)
37-
38-
const QuestionmarkLogo = () => (
39-
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 112 112">
40-
<path d="M0 0h112v112H0z" />
41-
<circle cx="56" cy="56" r="56" fill="#AFBACA" />
42-
<path d="M22 24h68v68H22z" />
43-
<path d="M27.667 35.333h56.667v45.333H27.667z" />
44-
<path
45-
fill="#fff"
46-
d="M84.333 41c0-3.117-2.55-5.667-5.666-5.667H33.333c-3.116 0-5.666 2.55-5.666 5.667v34c0 3.117 2.55 5.667 5.666 5.667h45.334c3.116 0 5.666-2.55 5.666-5.667V41zm-5.666 0L56 55.167 33.333 41h45.334zm0 34H33.333V46.667L56 60.833l22.667-14.166V75z"
47-
/>
48-
</svg>
49-
)
50-
/* eslint-enable max-len */
11+
const ProviderLogoWrapper = styled(Box)`
12+
svg,
13+
img {
14+
border-radius: 50%;
15+
height: 1.25em;
16+
width: 1.25em;
17+
}
18+
`
5119

52-
function getProviderLogo(provider) {
53-
switch (provider.name) {
54-
case 'google':
55-
return GoogleLogo
56-
case 'github':
57-
return GithubLogo
58-
default:
59-
return function CustomLogo() {
60-
return provider.logo ? (
61-
<img src={provider.logo} alt={`Logo for ${provider.name}`} />
62-
) : (
63-
<QuestionmarkLogo />
64-
)
65-
}
20+
const BrandLogoWrapper = styled(Box)`
21+
svg {
22+
display: block;
23+
height: 2rem;
24+
width: auto;
25+
margin: 0 auto;
6626
}
67-
}
27+
`
28+
29+
const projectName = (config.project && config.project.name) || ''
6830

6931
// eslint-disable-next-line react/require-optimization
7032
export default class LoginDialogContent extends React.Component {
@@ -96,61 +58,62 @@ export default class LoginDialogContent extends React.Component {
9658
render() {
9759
const {title, description, providers, SanityLogo} = this.props
9860
return (
99-
<div className={styles.root}>
100-
<div className={styles.inner}>
101-
{SanityLogo && (
102-
<div className={styles.sanityLogo}>
103-
<SanityLogo />
104-
</div>
61+
<Box paddingX={4} paddingY={5}>
62+
<Stack space={5}>
63+
{BrandLogo && projectName && (
64+
<BrandLogoWrapper>
65+
<BrandLogo projectName={projectName} />
66+
</BrandLogoWrapper>
10567
)}
68+
<Stack space={4}>
69+
{!BrandLogo && projectName && (
70+
<Heading align="center" as="h2" size={3}>
71+
{projectName}
72+
</Heading>
73+
)}
74+
{title && (
75+
<Text align="center" weight="semibold">
76+
{title}
77+
</Text>
78+
)}
79+
{description && (
80+
<Text size={1} muted align="center">
81+
{description}
82+
</Text>
83+
)}
84+
</Stack>
10685

107-
<div className={styles.card}>
108-
<div className={styles.cardHeader}>
109-
<h1 className={styles.cardTitle}>Sign in</h1>
110-
</div>
111-
112-
<div className={styles.cardContent}>
113-
<div className={styles.branding}>
114-
<h1 className={BrandLogo ? styles.projectNameHidden : styles.projectName}>
115-
{projectName}
116-
</h1>
117-
{BrandLogo && (
118-
<div className={styles.brandLogoContainer}>
119-
<BrandLogo projectName={projectName} />
120-
</div>
121-
)}
122-
</div>
123-
124-
<div>
125-
<h2 className={styles.title}>{title}</h2>
126-
{description && <div className={styles.description}>{description}</div>}
127-
</div>
128-
129-
<ul className={styles.providers}>
130-
{providers.map((provider) => {
131-
const ProviderLogo = getProviderLogo(provider)
132-
const onLoginClick = this.handleLoginButtonClicked.bind(this, provider)
133-
return (
134-
<li key={provider.name} className={styles.provider}>
135-
{/* eslint-disable-next-line react/jsx-no-bind */}
136-
<button
137-
type="button"
138-
onClick={onLoginClick}
139-
className={styles.providerButton}
140-
>
141-
<span className={styles.providerLogo}>
86+
<Stack space={2} as="ul">
87+
{providers?.map((provider) => {
88+
const ProviderLogo = getProviderLogo(provider)
89+
const onLoginClick = this.handleLoginButtonClicked.bind(this, provider)
90+
return (
91+
<Card key={provider?.name} radius={2} border as="li">
92+
<Button mode="bleed" paddingY={4} onClick={onLoginClick} style={{width: '100%'}}>
93+
<Flex justify="center">
94+
<Inline space={2}>
95+
<ProviderLogoWrapper>
14296
<ProviderLogo />
143-
</span>
144-
<span className={styles.providerName}>{provider.title}</span>
145-
</button>
146-
</li>
147-
)
148-
})}
149-
</ul>
150-
</div>
151-
</div>
152-
</div>
153-
</div>
97+
</ProviderLogoWrapper>
98+
<Box>
99+
<Text>{provider?.title}</Text>
100+
</Box>
101+
</Inline>
102+
</Flex>
103+
</Button>
104+
</Card>
105+
)
106+
})}
107+
</Stack>
108+
{SanityLogo && (
109+
<Flex justify="center" marginTop={2}>
110+
<Text>
111+
<SanityLogo />
112+
</Text>
113+
</Flex>
114+
)}
115+
</Stack>
116+
</Box>
154117
)
155118
}
156119
}

‎packages/@sanity/default-login/src/LoginWrapper.js

+13-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
import PropTypes from 'prop-types'
22
import React from 'react'
3-
import userStore from 'part:@sanity/base/user'
4-
5-
import LoginDialog from 'part:@sanity/base/login-dialog'
6-
import SanityStudioLogo from 'part:@sanity/base/sanity-studio-logo'
7-
import Spinner from 'part:@sanity/components/loading/spinner'
3+
import {SanityLogo as SanityLogotype} from '@sanity/logos'
4+
import {Spinner, Container, Flex} from '@sanity/ui'
85
import {of} from 'rxjs'
96
import {map, catchError} from 'rxjs/operators'
107
import CookieTest from './CookieTest'
118
import ErrorDialog from './ErrorDialog'
129
import UnauthorizedUser from './UnauthorizedUser'
1310
import {versionedClient} from './versionedClient'
11+
import {userStore, LoginDialog} from './legacyParts'
1412

1513
const isProjectLogin = versionedClient.config().useProjectHostname
1614
const projectId =
@@ -30,8 +28,14 @@ export default class LoginWrapper extends React.PureComponent {
3028
title: 'Choose a login provider',
3129
description: null,
3230
sanityLogo: null,
33-
SanityLogo: SanityStudioLogo,
34-
LoadingScreen: Spinner,
31+
SanityLogo: SanityLogotype,
32+
LoadingScreen: (
33+
<Container padding={4} height="fill">
34+
<Flex justify="center" align="center" height="fill">
35+
<Spinner />
36+
</Flex>
37+
</Container>
38+
),
3539
}
3640

3741
state = {isLoading: true, user: null, error: null}
@@ -52,8 +56,8 @@ export default class LoginWrapper extends React.PureComponent {
5256
)
5357
.subscribe({
5458
next: (userState) => {
55-
// Because observables _can_ be syncronous, it's not safe to call `setState` as it is a noop
56-
// We must therefore explicitly check whether or not we were call syncronously
59+
// Because observables _can_ be synchronous, it's not safe to call `setState` as it is a noop
60+
// We must therefore explicitly check whether or not we were call synchronously
5761
if (sync) {
5862
// eslint-disable-next-line react/no-direct-mutation-state
5963
this.state = {...this.state, ...userState}

‎packages/@sanity/default-login/src/UnauthorizedUser.js

+34-17
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,48 @@
11
import PropTypes from 'prop-types'
22
import React from 'react'
3-
import FullscreenMessageDialog from 'part:@sanity/components/dialogs/fullscreen-message'
43
import userStore from 'part:@sanity/base/user'
5-
import Button from 'part:@sanity/components/buttons/default'
4+
import {Dialog as UIDialog, Box, Text, Button, Stack} from '@sanity/ui'
5+
import styled from 'styled-components'
6+
7+
const Dialog = styled(UIDialog)`
8+
/* @todo: Temp solution. Update sanity/ui with option to hide close button */
9+
[aria-label='Close dialog'] {
10+
display: none;
11+
}
12+
`
613

714
function handleLogout() {
815
userStore.actions.logout()
916
}
1017

1118
export default function UnauthorizedUser(props) {
1219
return (
13-
<FullscreenMessageDialog
14-
buttons={<Button onClick={handleLogout}>Logout</Button>}
15-
title="Unauthorized"
20+
<Dialog
21+
header="Unauthorized"
22+
width={1}
23+
cardShadow={2}
24+
footer={
25+
<Box padding={3}>
26+
<Button text="Logout" onClick={handleLogout} style={{width: '100%'}} />
27+
</Box>
28+
}
1629
>
17-
<p>
18-
You are not authorized to access this studio. Maybe you could ask someone to invite you to
19-
collaborate on this project?
20-
</p>
21-
<p>
22-
If you think this is an error, verify that you are logged in with the correct account. You
23-
are currently logged in as{' '}
24-
<span>
25-
{props.user.name} ({props.user.email})
26-
</span>
27-
</p>
28-
</FullscreenMessageDialog>
30+
<Box paddingX={4} paddingY={5}>
31+
<Stack space={4}>
32+
<Text>
33+
You are not authorized to access this studio. Maybe you could ask someone to invite you
34+
to collaborate on this project?
35+
</Text>
36+
<Text>
37+
If you think this is an error, verify that you are logged in with the correct account.
38+
You are currently logged in as{' '}
39+
<span>
40+
{props.user.name} ({props.user.email})
41+
</span>
42+
</Text>
43+
</Stack>
44+
</Box>
45+
</Dialog>
2946
)
3047
}
3148

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import BrandLogo from 'part:@sanity/base/brand-logo?'
2+
import authenticationFetcher from 'part:@sanity/base/authentication-fetcher'
3+
import pluginConfig from 'config:@sanity/default-login'
4+
import LoginDialogContent from 'part:@sanity/base/login-dialog-content'
5+
import userStore from 'part:@sanity/base/user'
6+
import LoginDialog from 'part:@sanity/base/login-dialog'
7+
8+
export {BrandLogo, authenticationFetcher, pluginConfig, LoginDialogContent, userStore, LoginDialog}

‎packages/@sanity/default-login/src/styles/CookieTest.css

-65
This file was deleted.

‎packages/@sanity/default-login/src/styles/LoginDialog.css

-5
This file was deleted.

‎packages/@sanity/default-login/src/styles/LoginDialogContent.css

-134
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import React from 'react'
2+
3+
/* eslint-disable max-len */
4+
const GithubLogo = () => (
5+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 438.55 438.55">
6+
<path d="M409.13 114.57a218.32 218.32 0 0 0-79.8-79.8Q278.94 5.36 219.27 5.36T109.21 34.77a218.29 218.29 0 0 0-79.8 79.8Q0 165 0 224.63q0 71.67 41.83 128.91t108.06 79.23q7.71 1.43 11.42-2a11.17 11.17 0 0 0 3.69-8.57q0-.86-.14-15.42t-.14-25.41l-6.57 1.14a83.77 83.77 0 0 1-15.85 1 120.73 120.73 0 0 1-19.84-2 44.34 44.34 0 0 1-19.11-8.51 36.23 36.23 0 0 1-12.56-17.6l-2.86-6.57a71.34 71.34 0 0 0-9-14.56q-6.14-8-12.42-10.85l-2-1.43a21 21 0 0 1-3.71-3.43 15.66 15.66 0 0 1-2.57-4q-.86-2 1.43-3.29C61.2 310.42 64 310 68 310l5.71.85q5.71 1.14 14.13 6.85a46.08 46.08 0 0 1 13.85 14.84q6.57 11.71 15.85 17.85t18.7 6.14a81.19 81.19 0 0 0 16.27-1.42 56.78 56.78 0 0 0 12.85-4.29q2.57-19.14 14-29.41a195.49 195.49 0 0 1-29.36-5.13 116.52 116.52 0 0 1-26.83-11.14 76.86 76.86 0 0 1-23-19.13q-9.14-11.42-15-30t-5.8-42.81q0-34.55 22.56-58.82-10.57-26 2-58.24 8.28-2.57 24.55 3.85t23.84 11q7.57 4.56 12.13 7.71a206.2 206.2 0 0 1 109.64 0l10.85-6.85a153.65 153.65 0 0 1 26.26-12.56q15.13-5.71 23.13-3.14 12.84 32.26 2.28 58.24 22.55 24.27 22.56 58.82 0 24.27-5.85 43t-15.12 30a79.82 79.82 0 0 1-23.13 19 116.74 116.74 0 0 1-26.84 11.14 195.29 195.29 0 0 1-29.23 5.07q14.8 12.84 14.81 40.58v60.2a11.37 11.37 0 0 0 3.57 8.56q3.57 3.42 11.28 2 66.24-22 108.07-79.23t41.83-128.91q-.03-59.62-29.43-110.05z" />
7+
</svg>
8+
)
9+
10+
const GoogleLogo = () => (
11+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48">
12+
<path
13+
d="M11 24a13 13 0 0 1 .66-4.08l-7.4-5.66a22.18 22.18 0 0 0 0 19.49l7.4-5.67A13 13 0 0 1 11 24z"
14+
fill="#fbbc05"
15+
/>
16+
<path
17+
d="M24 11a12.72 12.72 0 0 1 8.1 2.9l6.4-6.4a22 22 0 0 0-34.24 6.75l7.4 5.66A13 13 0 0 1 24 11z"
18+
fill="#ea4335"
19+
/>
20+
<path
21+
d="M24 37a13 13 0 0 1-12.34-8.92l-7.4 5.66A21.93 21.93 0 0 0 24 46a21 21 0 0 0 14.33-5.48l-7-5.44A13.59 13.59 0 0 1 24 37zm-12.35-8.93l-7.4 5.67 7.4-5.66z"
22+
fill="#34a853"
23+
/>
24+
<path
25+
d="M44.5 20H24v8.5h11.8a9.91 9.91 0 0 1-4.49 6.58l7 5.44C42.37 36.76 45 31.17 45 24a18.25 18.25 0 0 0-.5-4z"
26+
fill="#4285f4"
27+
/>
28+
</svg>
29+
)
30+
31+
const QuestionmarkLogo = () => (
32+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 112 112">
33+
<path d="M0 0h112v112H0z" />
34+
<circle cx="56" cy="56" r="56" fill="#AFBACA" />
35+
<path d="M22 24h68v68H22z" />
36+
<path d="M27.667 35.333h56.667v45.333H27.667z" />
37+
<path
38+
fill="#fff"
39+
d="M84.333 41c0-3.117-2.55-5.667-5.666-5.667H33.333c-3.116 0-5.666 2.55-5.666 5.667v34c0 3.117 2.55 5.667 5.666 5.667h45.334c3.116 0 5.666-2.55 5.666-5.667V41zm-5.666 0L56 55.167 33.333 41h45.334zm0 34H33.333V46.667L56 60.833l22.667-14.166V75z"
40+
/>
41+
</svg>
42+
)
43+
/* eslint-enable max-len */
44+
45+
export function getProviderLogo(provider) {
46+
switch (provider.name) {
47+
case 'google':
48+
return GoogleLogo
49+
case 'github':
50+
return GithubLogo
51+
default:
52+
return function CustomLogo() {
53+
return provider.logo ? (
54+
<img src={provider.logo} alt={`Logo for ${provider.name}`} />
55+
) : (
56+
<QuestionmarkLogo />
57+
)
58+
}
59+
}
60+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"extends": "../../../tsconfig.settings",
3+
"include": ["src"],
4+
"compilerOptions": {
5+
"composite": true,
6+
"outDir": "./lib",
7+
"rootDir": "./src",
8+
"jsx": "react",
9+
"noImplicitAny": false,
10+
}
11+
}

2 commit comments

Comments
 (2)

vercel[bot] commented on Jul 9, 2021

@vercel[bot]

Successfully deployed to the following URLs:

perf-studio – ./

perf-studio-git-next.sanity.build
perf-studio.sanity.build

vercel[bot] commented on Jul 9, 2021

@vercel[bot]

Successfully deployed to the following URLs:

test-studio – ./

test-studio.sanity.build
test-studio-git-next.sanity.build

Please sign in to comment.