on master help sign in
address design issues
1cf45c8Liam Fitzgerald
src/components/Chip.js+2−4
@@ -1,14 +1,12 @@
1import React from 'react';
1import React from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3
3
4−export default function Chip({ children, color, className }) {
4+export default function Chip({ children, bgColor, fgColor, className }) {
5− const bgColor = `bg-${color}1`;
6− const fgColor = `${color}4`;
7 return (
5 return (
8 <div
6 <div
9 className={cn(
7 className={cn(
10 className,
8 className,
11− 'h6 r-full flex-center ph2 mh2',
9+ 'h6 r-full flex-center ph2 mh2 f6',
12 bgColor,
10 bgColor,
13 fgColor
11 fgColor
14 )}>
12 )}>
src/components/InviteSigilList.js+1−1
@@ -44,7 +44,7 @@ const InviteSigilList = ({ className, pendingPoints, acceptedPoints }) => {
44 <div className={cn('flex justify-between', className)}>
44 <div className={cn('flex justify-between', className)}>
45 {renderSigil(_acceptedPoints, ['#000000', '#FFFFFF'])}
45 {renderSigil(_acceptedPoints, ['#000000', '#FFFFFF'])}
46 {renderSigil(_pendingPoints, ['#ee892b', '#FFFFFF'])}
46 {renderSigil(_pendingPoints, ['#ee892b', '#FFFFFF'])}
47− {renderSigil(empty, [], 'b1 b-black b-dashed')}
47+ {renderSigil(empty, [], 'b1 b-gray3 b-dashed')}
48 </div>
48 </div>
49 );
49 );
50};
50};
src/indigo-react/components/Button.js+7−2
@@ -19,6 +19,7 @@ export default function Button({
19 background,
19 background,
20 type,
20 type,
21 children,
21 children,
22+ center = false,
22 ...rest
23 ...rest
23}) {
24}) {
24 const handleKeyPress = e => {
25 const handleKeyPress = e => {
@@ -60,10 +61,14 @@ export default function Button({
60 onClick={!disabled && onClick ? onClick : undefined}
61 onClick={!disabled && onClick ? onClick : undefined}
61 {...rest}>
62 {...rest}>
62 {background}
63 {background}
64+ <Grid.Item
65+ full
66+ as={Flex}
63− <Grid.Item full as={Flex} justify="between" className="z2">
67+ justify="between"
68+ className={cn('z2', { 'flex-center': center })}>
64 <span>{children}</span>
69 <span>{children}</span>
65 {type && <button type={type} style={{ display: 'none' }}></button>}
70 {type && <button type={type} style={{ display: 'none' }}></button>}
66− <div className={cn('pl4')}>{accessory}</div>
71+ {!center && <div className={cn('pl4')}>{accessory}</div>}
67 </Grid.Item>
72 </Grid.Item>
68 {detail && (
73 {detail && (
69 <Grid.Item full as={HelpText} className={cn('z2', detailClassName)}>
74 <Grid.Item full as={HelpText} className={cn('z2', detailClassName)}>
src/views/Invite/Cohort.js+23−13
@@ -1,5 +1,5 @@
1import React, { useMemo, useEffect, useCallback, useState } from 'react';
1import React, { useMemo, useEffect, useCallback, useState } from 'react';
2−import { Grid, Flex } from 'indigo-react';
2+import { Grid, Flex, Button } from 'indigo-react';
3import * as ob from 'urbit-ob';
3import * as ob from 'urbit-ob';
4import { Just } from 'folktale/maybe';
4import { Just } from 'folktale/maybe';
5import cn from 'classnames';
5import cn from 'classnames';
@@ -9,9 +9,9 @@ import { usePointCache } from 'store/pointCache';
9
9
10import View from 'components/View';
10import View from 'components/View';
11import BarGraph from 'components/BarGraph';
11import BarGraph from 'components/BarGraph';
12−import InviteSigilList from 'components/InviteSigilList';
13import MaybeSigil from 'components/MaybeSigil';
12import MaybeSigil from 'components/MaybeSigil';
14import { matchBlinky } from 'components/Blinky';
13import { matchBlinky } from 'components/Blinky';
14+import { ForwardButton } from 'components/Buttons';
15import Chip from 'components/Chip';
15import Chip from 'components/Chip';
16import Crumbs from 'components/Crumbs';
16import Crumbs from 'components/Crumbs';
17
17
@@ -19,6 +19,8 @@ import { useLocalRouter } from 'lib/LocalRouter';
19import useInvites from 'lib/useInvites';
19import useInvites from 'lib/useInvites';
20import * as need from 'lib/need';
20import * as need from 'lib/need';
21
21
22+import Inviter from 'views/Invite/Inviter';
23+
22import { ReactComponent as SearchIcon } from 'assets/search.svg';
24import { ReactComponent as SearchIcon } from 'assets/search.svg';
23
25
24function CohortMember({ point, className }) {
26function CohortMember({ point, className }) {
@@ -73,8 +75,8 @@ function CohortList({ points, className }) {
73 return (
75 return (
74 <Grid gap={3} className={cn('mt1', className)}>
76 <Grid gap={3} className={cn('mt1', className)}>
75 <Grid.Item align="center" full as={Flex} className="b b-gray2 b1">
77 <Grid.Item align="center" full as={Flex} className="b b-gray2 b1">
76− <Flex.Item>
78+ <Flex.Item className="p2">
77− <SearchIcon className="p2" />
79+ <SearchIcon />
78 </Flex.Item>
80 </Flex.Item>
79
81
80 <Flex.Item
82 <Flex.Item
@@ -82,7 +84,7 @@ function CohortList({ points, className }) {
82 as={'input'}
84 as={'input'}
83 value={query}
85 value={query}
84 onChange={handleChange}
86 onChange={handleChange}
85− className="b-none"
87+ className="b-none h7"
86 />
88 />
87 </Grid.Item>
89 </Grid.Item>
88 <>
90 <>
@@ -113,6 +115,8 @@ export default function InviteCohort() {
113 sentInvites,
115 sentInvites,
114 } = useInvites(point);
116 } = useInvites(point);
115
117
118+ const [showInviteForm, setShowInviteForm] = useState(false);
119+
116 const _acceptedPoints = acceptedPoints.getOrElse([]);
120 const _acceptedPoints = acceptedPoints.getOrElse([]);
117 const _pendingPoints = pendingPoints.getOrElse([]);
121 const _pendingPoints = pendingPoints.getOrElse([]);
118 const _pendingInvites = _pendingPoints.length;
122 const _pendingInvites = _pendingPoints.length;
@@ -140,8 +144,8 @@ export default function InviteCohort() {
140 <Flex.Item>
144 <Flex.Item>
141 {_acceptedInvites + _pendingInvites} / {_totalInvites}
145 {_acceptedInvites + _pendingInvites} / {_totalInvites}
142 </Flex.Item>
146 </Flex.Item>
143− {_pendingInvites && (
147+ {_pendingInvites !== 0 && (
144− <Flex.Item as={Chip} color="yellow">
148+ <Flex.Item as={Chip} className="bg-yellow4 white">
145 {_pendingInvites} pending
149 {_pendingInvites} pending
146 </Flex.Item>
150 </Flex.Item>
147 )}
151 )}
@@ -154,12 +158,18 @@ export default function InviteCohort() {
154 sent={sentInvites}
158 sent={sentInvites}
155 accepted={acceptedInvites}
159 accepted={acceptedInvites}
156 />
160 />
161+ {availableInvites.getOrElse(0) !== 0 && !showInviteForm && (
157− <Grid.Item
162+ <Grid.Item
158− full
163+ full
159− as={InviteSigilList}
164+ solid
160− pendingPoints={pendingPoints}
165+ center
161− acceptedPoints={acceptedPoints}
166+ as={Button}
162− />
167+ onClick={() => setShowInviteForm(true)}>
168+ Add Members
169+ </Grid.Item>
170+ )}
171+ {showInviteForm && <Inviter />}
172+
163 <Grid.Item full as={CohortList} points={_acceptedPoints} />
173 <Grid.Item full as={CohortList} points={_acceptedPoints} />
164 </Grid>
174 </Grid>
165 </View>
175 </View>
src/views/Invite/Email.js+1−1
@@ -92,7 +92,7 @@ const InviteMail = ({ setSubmitting }) => {
92 setSubmitting(false);
92 setSubmitting(false);
93 setStatus(STATUS.SUCCESS);
93 setStatus(STATUS.SUCCESS);
94 },
94 },
95− [generateInvites, setCount, setStatus, sendInvites]
95+ [generateInvites, setCount, setStatus, sendInvites, setSubmitting]
96 );
96 );
97
97
98 const validateHasReceived = useCallback(
98 const validateHasReceived = useCallback(
src/views/Invite/Url.js+14−13
@@ -1,5 +1,5 @@
1import React, { useCallback, useState } from 'react';
1import React, { useCallback, useState } from 'react';
2−import { Grid, ErrorText } from 'indigo-react';
2+import { Grid, ErrorText, Flex } from 'indigo-react';
3import { get } from 'lodash';
3import { get } from 'lodash';
4import { FORM_ERROR } from 'final-form';
4import { FORM_ERROR } from 'final-form';
5
5
@@ -30,7 +30,8 @@ const InviteUrl = ({ setSubmitting }) => {
30 if (hasErrors(errors)) {
30 if (hasErrors(errors)) {
31 setError(errors);
31 setError(errors);
32 }
32 }
33+ setSubmitting(false);
33− }, [generateInvites]);
34+ }, [generateInvites, setSubmitting]);
34
35
35 const renderGenerateButton = useCallback(() => {
36 const renderGenerateButton = useCallback(() => {
36 if (error) {
37 if (error) {
@@ -75,21 +76,21 @@ const InviteUrl = ({ setSubmitting }) => {
75 const [doCopy, didCopy] = useCopiable(url);
76 const [doCopy, didCopy] = useCopiable(url);
76
77
77 return (
78 return (
78− <Grid.Item full as={Grid}>
79+ <Grid.Item full as={Grid} gap={3}>
79 {invites.length > 0 && (
80 {invites.length > 0 && (
80− <>
81+ <Grid.Item as={Flex} full col>
81− <Grid.Item full className="b-gray3 b1 mv4 p1 flex flex-center">
82+ <Flex.Item full className="b-gray3 b1 mt4 mb1 p1 flex flex-center">
82− <div className="flex1 ml1">{url}</div>
83+ <div className="flex1 ml1 f6">{url}</div>
83− <Grid.Item
84+ <Flex.Item
84− className="pv3 ph4 bg-black white"
85+ className="p2 bg-black white pointer-hover f6"
85 onClick={() => doCopy()}>
86 onClick={() => doCopy()}>
86 {didCopy ? 'Copied' : 'Copy'}
87 {didCopy ? 'Copied' : 'Copy'}
87− </Grid.Item>
88+ </Flex.Item>
88− </Grid.Item>
89+ </Flex.Item>
89− <Grid.Item full>
90+ <Flex.Item full className="f6 mb4 gray5">
90 Your invite link expires after consumption.
91 Your invite link expires after consumption.
91− </Grid.Item>
92+ </Flex.Item>
92− </>
93+ </Grid.Item>
93 )}
94 )}
94 {invites.length === 0 && renderGenerateButton()}
95 {invites.length === 0 && renderGenerateButton()}
95 {needFunds && <Grid.Item full as={NeedFundsNotice} {...needFunds} />}
96 {needFunds && <Grid.Item full as={NeedFundsNotice} {...needFunds} />}
src/views/Point.js+6−4
@@ -1,7 +1,7 @@
1import React, { useCallback, useState } from 'react';
1import React, { useCallback, useState } from 'react';
2import cn from 'classnames';
2import cn from 'classnames';
3import { Just } from 'folktale/maybe';
3import { Just } from 'folktale/maybe';
4−import { Grid, Flex } from 'indigo-react';
4+import { Grid, Flex, Button } from 'indigo-react';
5import { azimuth } from 'azimuth-js';
5import { azimuth } from 'azimuth-js';
6
6
7import { usePointCursor } from 'store/pointCursor';
7import { usePointCursor } from 'store/pointCursor';
@@ -149,7 +149,7 @@ export default function Point() {
149 </Grid.Item>
149 </Grid.Item>
150
150
151 <Grid.Item
151 <Grid.Item
152− className={cn('t-right underline', {
152+ className={cn('t-right underline pointer-hover', {
153 gray4: sentInvites.getOrElse(0) === 0,
153 gray4: sentInvites.getOrElse(0) === 0,
154 })}
154 })}
155 onClick={goCohort}
155 onClick={goCohort}
@@ -163,7 +163,7 @@ export default function Point() {
163 {_totalInvites}
163 {_totalInvites}
164 </Flex.Item>
164 </Flex.Item>
165 {_pendingInvites > 0 && (
165 {_pendingInvites > 0 && (
166− <Flex.Item as={Chip} color="yellow">
166+ <Flex.Item as={Chip} className="bg-yellow1 yellow4">
167 {_pendingInvites} pending
167 {_pendingInvites} pending
168 </Flex.Item>
168 </Flex.Item>
169 )}
169 )}
@@ -200,12 +200,14 @@ export default function Point() {
200 <Grid.Item
200 <Grid.Item
201 full
201 full
202 solid
202 solid
203− as={ForwardButton}
203+ as={Button}
204+ center
204 onClick={() => setShowInviteForm(true)}>
205 onClick={() => setShowInviteForm(true)}>
205 Add Members
206 Add Members
206 </Grid.Item>
207 </Grid.Item>
207 )}
208 )}
208 {showInviteForm && <Inviter />}
209 {showInviteForm && <Inviter />}
210+ <Grid.Item full className="mb2" />
209 </>
211 </>
210 )}
212 )}
211 {!loadedInvites && isPlanet && (
213 {!loadedInvites && isPlanet && (